From 019e5cfb438cc2e66a328f4e50558b10a7db4a94 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 04:18:42 +0200 Subject: [PATCH 01/10] Build 1.21.11 with Stonecutter from a shared src/ Step 1 of #8. 1.21.11's version-specific code moves from versions/1.21.11/src to the top-level src/, built by Stonecutter as the project :1.21.11. The other versions still build from their own copies as :mc- until they're folded in. - settings.gradle: applies Stonecutter (Groovy controller) with stonecutterVersions = ["1.21.11"] and skips those folders when including the old mc- projects. - The old root build.gradle becomes stonecutter.gradle (the root project's script, with the shared repositories, common wiring and buildAll), and 1.21.11's build.gradle becomes the root build.gradle that Stonecutter runs for each version. versions/1.21.11 keeps its gradle.properties and run/. - The jar has the same 415 entries, fabric.mod.json and mixin configs as before; the only class differences also appear when rebuilding an untouched version today. - scripts/port.sh treats src/ as the active Stonecutter version, so changes port between it and the old copies both ways. - README and VERSION_GUIDE describe the layout, version comments and how to add a version. Co-Authored-By: Claude Opus 5.5 --- README.MD | 4 +- VERSION_GUIDE.md | 42 +++-- build.gradle | 148 +++++++++++------- scripts/port.sh | 64 +++++--- settings.gradle | 27 +++- .../impl/cosmetics/CloakFeatureRenderer.java | 0 .../impl/cosmetics/HatFeatureRenderer.java | 0 .../impl/cosmetics/obj/MtlLoader.java | 0 .../impl/cosmetics/obj/ObjModel.java | 0 .../impl/cosmetics/obj/ObjRenderer.java | 0 .../impl/cosmetics/utils/IdentifierUtils.java | 0 .../impl/cosmetics/utils/ShaderUtils.java | 0 .../entity/CameraOverriddenEntity.java | 0 .../features/entity/EntityFeatureImpl.java | 0 .../features/entity/HealthRenderState.java | 0 .../features/mixins/entity/CameraMixin.java | 0 .../features/mixins/entity/EntityMixin.java | 0 .../render/BackgroundRendererMixin.java | 0 .../mixins/render/GameRendererMixin.java | 0 .../render/LightmapTextureManagerMixin.java | 0 .../render/LivingEntityRenderStateMixin.java | 0 .../render/LivingEntityRendererMixin.java | 0 .../features/mixins/render/RenderMixin.java | 0 .../impl/features/mixins/world/TpsMixin.java | 0 .../features/network/NetworkFeatureImpl.java | 0 .../features/player/PlayerFeatureImpl.java | 0 .../features/render/RenderFeatureImpl.java | 0 .../impl/features/world/WorldFeatureImpl.java | 0 .../impl/mixins/IdentifierMixin.java | 0 .../impl/mixins/ItemStackMixin.java | 0 .../impl/mixins/MinecraftClientMixin.java | 0 .../impl/mixins/QuaternionfMixin.java | 0 .../saturnclient/impl/mixins/SpriteMixin.java | 0 .../impl/mixins/StatusEffectMixin.java | 0 .../saturnclient/impl/mixins/TextMixin.java | 0 .../saturnclient/impl/mixins/WindowMixin.java | 0 .../impl/provider/FeatureProviderFabric.java | 0 .../impl/provider/GLFWProviderImpl.java | 0 .../impl/provider/RefConstructorImpl.java | 0 .../impl/provider/SaturnProviderImpl.java | 0 .../impl/ref/Matrix3x2fStackRef.java | 0 .../impl/ui/EntityDrawerImpl.java | 0 .../saturnclient/impl/ui/RenderScopeImpl.java | 0 .../impl/ui/SaturnScreenFabric.java | 0 .../saturnclient/SaturnClient.java | 0 .../saturnclient/SaturnRenderState.java | 0 .../saturnclient/event/KeyInputHandler.java | 0 .../mixin/DrawContextAccessor.java | 0 .../mixin/PlayerEntityRendererMixin.java | 0 .../saturnclient/mixin/SetScreenMixin.java | 0 .../mixin/SplashOverlayMixin.java | 0 .../saturnclient/mixin/TabListMixin.java | 0 .../saturnclient/mixin/WhoAmI.java | 0 .../main/resources/fabric.mod.json | 0 .../main/resources/features.mixins.json | 0 .../main/resources/impl.mixins.json | 0 .../main/resources/saturnclient.mixins.json | 0 stonecutter.gradle | 73 +++++++++ versions/1.21.11/build.gradle | 101 ------------ versions/1.21.11/settings.gradle | 10 -- 60 files changed, 267 insertions(+), 202 deletions(-) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/SpriteMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/TextMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/mixins/WindowMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/SaturnClient.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/SaturnRenderState.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java (100%) rename {versions/1.21.11/src => src}/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java (100%) rename {versions/1.21.11/src => src}/main/resources/fabric.mod.json (100%) rename {versions/1.21.11/src => src}/main/resources/features.mixins.json (100%) rename {versions/1.21.11/src => src}/main/resources/impl.mixins.json (100%) rename {versions/1.21.11/src => src}/main/resources/saturnclient.mixins.json (100%) create mode 100644 stonecutter.gradle delete mode 100644 versions/1.21.11/build.gradle delete mode 100644 versions/1.21.11/settings.gradle diff --git a/README.MD b/README.MD index 3e5f9a8..578a3d2 100644 --- a/README.MD +++ b/README.MD @@ -47,8 +47,8 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :mc-1.21.11:build # a single version -./gradlew :mc-1.21.11:runClient # launch a development client +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.10) +./gradlew :1.21.11:runClient # launch a development client ``` Building needs Java 21. diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index 1ce18db..e851152 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -4,12 +4,30 @@ How Saturn Client supports several Minecraft versions, and how to change or add ## Layout -- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `versions//`: one module per Minecraft version, implementing those interfaces (providers, refs, mixins). Each is a full copy, and they differ only where Minecraft's API differs. - - `gradle.properties`: the Minecraft, Yarn, Fabric Loader and Fabric API versions. - - `src/`: the version-specific code and the three mixin configs. +Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: -`settings.gradle` includes every folder under `versions/` automatically, as the Gradle project `:mc-`. +- `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.10), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. + +`settings.gradle` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle` builds each Stonecutter version, and `stonecutter.gradle` configures the root project (shared repositories, the `common` wiring and `buildAll`). + +## Version-specific code with Stonecutter + +The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle`). Code for other versions sits in comments that Stonecutter swaps before building each version: + +```java +//? if >=1.21.9 { +public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { +//?} else +/*public void render(MatrixStack matrices, VertexConsumerProvider consumers, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) {*/ +``` + +- `./gradlew "Set active project to "` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE. +- `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active. +- Each version's processed copy is compiled from `versions//build/generated/stonecutter/`, which is also where to look when a non-active version fails to compile. + +The `emotes` repository uses the same setup, and its `BentCubeRenderer` and `PlayerModelMixin` are small examples of version comments. ## Porting a change to the other versions @@ -22,13 +40,13 @@ scripts/port.sh --to 1.21.9,1.21.10 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` -The script applies the diff under `versions//src` to each other version with `git apply --3way`: +The script applies the diff under one version's source to each other version with `git apply --3way`. The Stonecutter `src/` counts as one version (1.21.11), so changes port between it and the old copies in both directions: - **applied**: the files matched, and nothing else is needed. - **CONFLICTS**: that version's code really differs. The file gets normal conflict markers, with the version's own code in `ours` and the ported change in `theirs`. Adapt the change to that version's API and resolve. - **already has this change**: nothing to do, which is safe to see when re-running. -Only `src/` is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything: +Only source is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything: ```sh ./gradlew compileJava @@ -38,7 +56,9 @@ The **Check** workflow runs the same compile on every pull request, so a version ## Adding a Minecraft version -1. Copy the closest existing version: `cp -r versions/1.21.11 versions/`. Delete its `build/`, `.gradle/` and `run/` folders if present. -2. In `versions//gradle.properties`, set `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version`. The right values are listed at . -3. Build it with `./gradlew :mc-:compileJava` and fix what Minecraft changed. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew :mc-:runClient`. -4. The release workflow builds every folder under `versions/`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing. +Add new versions to Stonecutter rather than copying a folder: + +1. Create `versions//gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at ). +2. Add `` to `stonecutterVersions` in `settings.gradle`. +3. Build it with `./gradlew ::compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew ::runClient`. +4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing. diff --git a/build.gradle b/build.gradle index 1589821..b40015c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,65 +1,101 @@ -subprojects { - apply plugin: "java" +plugins { + id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" + id 'maven-publish' +} - repositories { - maven { url "https://maven.fabricmc.net/" } - maven { url "https://git.selimaj.dev/api/packages/selimaj-dev/maven" } - maven { url "https://git.selimaj.dev/api/packages/saturnclientmc/maven" } - mavenCentral() - } +version = "${project.mod_version}+${project.minecraft_version}" +group = project.maven_group - dependencies { - implementation "de.javagl:obj:0.4.0" - implementation "com.formdev:svgSalamander:1.1.4" - implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0' - implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.0' - implementation 'com.fasterxml.jackson.core:jackson-core:2.17.0' +base { + archivesName = project.archives_base_name +} + +repositories { + maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" + + // Saturn's emote library (limb bending, Emotecraft emotes) + include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") + + implementation project(":common") + + include implementation("dev.selimaj:session-java:0.2.0") + include implementation("de.javagl:obj:0.4.0") + include implementation("com.formdev:svgSalamander:1.1.4") + include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") + include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") + include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") +} + +/* + * ================================================================ + * Resource Processing + * ================================================================ + * Injects version values into fabric.mod.json. + */ +processResources { + inputs.property "version", project.version + inputs.property "minecraft_version", project.minecraft_version + inputs.property "loader_version", project.loader_version + filteringCharset "UTF-8" + + filesMatching("fabric.mod.json") { + expand( + "version": project.version, + "minecraft_version": project.minecraft_version, + "loader_version": project.loader_version + ) } } -configure(subprojects.findAll { it.name != "common" }) { - dependencies { - implementation project(":common") - } - - sourceSets { - main { - resources { - srcDir project(":common").file("src/main/resources") - } - } - } +tasks.withType(JavaCompile).configureEach { + it.options.release = 21 } -tasks.register("buildAll") { - group = "build" - description = "Builds all subprojects and collects their remapped jars" +java { + // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task + // if it is present. + // If you remove this line, sources will not be generated. + withSourcesJar() - // Only build remapped jars (not full build) - dependsOn subprojects.collect { proj -> - proj.tasks.matching { it.name == "remapJar" } - } - - doLast { - def outputDir = file("$buildDir/allJars") - outputDir.mkdirs() - - subprojects.each { proj -> - def remapTask = proj.tasks.findByName("remapJar") - - if (remapTask != null) { - def jarFile = remapTask.archiveFile.get().asFile - - if (jarFile.exists() && !jarFile.name.contains("sources")) { - copy { - from jarFile - into outputDir - rename { "${jarFile.name}" } - } - } - } - } - - println "All remapped jars collected in: $outputDir" - } + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } + +jar { + inputs.property "archivesName", project.base.archivesName + + from("LICENSE") { + rename { "${it}_${inputs.properties.archivesName}"} + } + + from project(":common").sourceSets.main.output + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + +// configure the maven publication +publishing { + publications { + create("mavenJava", MavenPublication) { + artifactId = project.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. + } +} \ No newline at end of file diff --git a/scripts/port.sh b/scripts/port.sh index a0976e1..5f22636 100755 --- a/scripts/port.sh +++ b/scripts/port.sh @@ -1,11 +1,15 @@ #!/usr/bin/env bash # Port a change made in one Minecraft version's code to the other versions. # -# Takes the diff under versions//src and applies it to versions//src +# Takes the diff under one version's source folder and applies it to the others # with `git apply --3way`: it applies cleanly where the files match, and leaves -# normal merge conflicts only where a version really differs. Only src/ is +# normal merge conflicts only where a version really differs. Only source is # ported; build.gradle and gradle.properties are version-specific on purpose. # +# Versions moved to Stonecutter (stonecutterVersions in settings.gradle) share +# the top-level src/, which counts as one version: the active one set in +# stonecutter.gradle. The others keep their own copy in versions//src. +# # Usage: # scripts/port.sh [--from VERSION] [--to V1,V2,...] [--commit REV] [--dry-run] # @@ -33,25 +37,39 @@ while [ $# -gt 0 ]; do --to) to="$2"; shift 2 ;; --commit) commit="$2"; shift 2 ;; --dry-run) dry_run=true; shift ;; - -h|--help) sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + -h|--help) sed -n '2,23p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; *) echo "Unknown option: $1 (see --help)" >&2; exit 2 ;; esac done -all_versions=$(ls -d versions/*/ | xargs -n1 basename | sort -t. -k1,1n -k2,2n -k3,3n) +# Versions sharing the Stonecutter src/, and the one that stands for them. +stonecutter_versions=$(sed -n 's/^def stonecutterVersions = \[\(.*\)\]/\1/p' settings.gradle | tr -d '" ' | tr ',' ' ') +stonecutter_active=$(sed -n 's/^stonecutter\.active "\(.*\)"/\1/p' stonecutter.gradle 2>/dev/null || true) + +is_stonecutter() { + printf '%s\n' $stonecutter_versions | grep -qx "$1" +} + +# Where a version's source lives. +src_of() { + if is_stonecutter "$1"; then echo "src"; else echo "versions/$1/src"; fi +} + +old_versions=$(for d in versions/*/; do [ -d "$d/src" ] && basename "$d"; done) +all_versions=$(printf '%s\n' $old_versions $stonecutter_active | grep . | sort -t. -k1,1n -k2,2n -k3,3n) version_exists() { - [ -d "versions/$1/src" ] + [ -d "$(src_of "$1")" ] } # Versions with changes, from the working tree or from the given commit. changed_versions() { if [ -n "$commit" ]; then - git show --name-only --format= "$commit" -- versions/ + git show --name-only --format= "$commit" -- versions/ src/ else - git diff HEAD --name-only -- versions/ - git ls-files --others --exclude-standard -- versions/ - fi | sed -n 's#^versions/\([^/]*\)/src/.*#\1#p' | sort -u + git diff HEAD --name-only -- versions/ src/ + git ls-files --others --exclude-standard -- versions/ src/ + fi | sed -n -e 's#^versions/\([^/]*\)/src/.*#\1#p' -e "s#^src/.*#${stonecutter_active}#p" | sort -u } if [ -z "$from" ]; then @@ -65,6 +83,10 @@ if [ -z "$from" ]; then fi version_exists "$from" || { echo "No such version: $from" >&2; exit 2; } +if is_stonecutter "$from"; then + from="$stonecutter_active" +fi +from_src=$(src_of "$from") if [ -z "$to" ]; then to=$(printf '%s\n' $all_versions | grep -vx "$from" | paste -sd, -) @@ -72,10 +94,10 @@ fi # New files are only included in `git diff HEAD` once git knows about them. if [ -z "$commit" ]; then - untracked=$(git ls-files --others --exclude-standard -- "versions/$from/src") + untracked=$(git ls-files --others --exclude-standard -- "$from_src") if [ -n "$untracked" ]; then if $dry_run; then - echo "note: new files in versions/$from/src are untracked and won't be ported in a dry run:" >&2 + echo "note: new files in $from_src are untracked and won't be ported in a dry run:" >&2 printf ' %s\n' $untracked >&2 else printf '%s\n' "$untracked" | xargs git add --intent-to-add -- @@ -85,20 +107,20 @@ fi # --full-index gives --3way the real blob ids to merge against. if [ -n "$commit" ]; then - patch=$(git show --full-index --binary --format= "$commit" -- "versions/$from/src") + patch=$(git show --full-index --binary --format= "$commit" -- "$from_src") else - patch=$(git diff HEAD --full-index --binary -- "versions/$from/src") + patch=$(git diff HEAD --full-index --binary -- "$from_src") fi if [ -z "$patch" ]; then - echo "No changes under versions/$from/src to port." >&2 + echo "No changes under $from_src to port." >&2 exit 2 fi files=$(printf '%s\n' "$patch" | grep -c '^diff --git' || true) echo "Porting $files file(s) from $from${commit:+ (commit $commit)}" -from_re=$(printf '%s' "$from" | sed 's/\./\\./g') +from_re=$(printf '%s' "$from_src" | sed 's/\./\\./g') tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT @@ -109,14 +131,20 @@ for target in "${targets[@]}"; do if [ "$target" = "$from" ]; then continue fi + if is_stonecutter "$target" && [ "$target" != "$stonecutter_active" ]; then + printf ' %-8s skipped: shares src/ with %s\n' "$target" "$stonecutter_active" + [ "$from" = "$stonecutter_active" ] || status=1 + continue + fi if ! version_exists "$target"; then printf ' %-8s skipped: no such version\n' "$target" status=1 continue fi - # Point the patch's file headers at the target version. - printf '%s\n' "$patch" | sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ s#versions/${from_re}/#versions/${target}/#g" > "$tmp/$target.patch" + # Point the patch's file headers at the target version's source folder. + target_src=$(src_of "$target") + printf '%s\n' "$patch" | sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ s#([ab]/|(from|to) )${from_re}/#\1${target_src}/#g" > "$tmp/$target.patch" if git apply --check --reverse "$tmp/$target.patch" 2>/dev/null; then printf ' %-8s already has this change\n' "$target" @@ -135,7 +163,7 @@ for target in "${targets[@]}"; do if output=$(git apply --3way "$tmp/$target.patch" 2>&1); then printf ' %-8s applied\n' "$target" else - conflicts=$(git diff --name-only --diff-filter=U -- "versions/$target") + conflicts=$(git diff --name-only --diff-filter=U -- "$target_src") if [ -n "$conflicts" ]; then printf ' %-8s CONFLICTS in:\n' "$target" printf '%s\n' "$conflicts" | sed 's/^/ /' diff --git a/settings.gradle b/settings.gradle index 07bdcaa..95f2676 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,21 +1,40 @@ pluginManagement { repositories { maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.kikugie.dev/releases" } gradlePluginPortal() mavenCentral() } } +plugins { + id "dev.kikugie.stonecutter" version "0.9.8" +} + rootProject.name = "saturn-client" include("common") -def versionsDir = file("versions") +// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle). Each one's +// versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. +def stonecutterVersions = ["1.21.11"] -versionsDir.eachDir { dir -> - def version = dir.name - def projectName = "mc-${version}" +stonecutter { + kotlinController = false // stonecutter.gradle configures the root project + centralScript = "build.gradle" // build.gradle configures each version + create(rootProject) { + versions(*stonecutterVersions) + vcsVersion = "1.21.11" + } +} +// Versions not moved to Stonecutter yet still build from their own copy in versions//src, +// as projects named mc-. +file("versions").eachDir { dir -> + if (dir.name in stonecutterVersions) { + return + } + def projectName = "mc-${dir.name}" include(projectName) project(":${projectName}").projectDir = dir } diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java rename to src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java rename to src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java rename to src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java rename to src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java rename to src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java rename to src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java rename to src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java rename to src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java rename to src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java rename to src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java rename to src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java rename to src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java rename to src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java rename to src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java rename to src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java rename to src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java rename to src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java rename to src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java rename to src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java rename to src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/src/main/java/org/saturnclient/impl/mixins/TextMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/TextMixin.java rename to src/main/java/org/saturnclient/impl/mixins/TextMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java rename to src/main/java/org/saturnclient/impl/mixins/WindowMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java rename to src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java rename to src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java rename to src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java rename to src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java rename to src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java rename to src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java rename to src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java rename to src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/SaturnClient.java rename to src/main/java/org/saturnclient/saturnclient/SaturnClient.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java rename to src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java rename to src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java rename to src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java rename to src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java rename to src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java rename to src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java rename to src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java diff --git a/versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java similarity index 100% rename from versions/1.21.11/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java rename to src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java diff --git a/versions/1.21.11/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json similarity index 100% rename from versions/1.21.11/src/main/resources/fabric.mod.json rename to src/main/resources/fabric.mod.json diff --git a/versions/1.21.11/src/main/resources/features.mixins.json b/src/main/resources/features.mixins.json similarity index 100% rename from versions/1.21.11/src/main/resources/features.mixins.json rename to src/main/resources/features.mixins.json diff --git a/versions/1.21.11/src/main/resources/impl.mixins.json b/src/main/resources/impl.mixins.json similarity index 100% rename from versions/1.21.11/src/main/resources/impl.mixins.json rename to src/main/resources/impl.mixins.json diff --git a/versions/1.21.11/src/main/resources/saturnclient.mixins.json b/src/main/resources/saturnclient.mixins.json similarity index 100% rename from versions/1.21.11/src/main/resources/saturnclient.mixins.json rename to src/main/resources/saturnclient.mixins.json diff --git a/stonecutter.gradle b/stonecutter.gradle new file mode 100644 index 0000000..131f357 --- /dev/null +++ b/stonecutter.gradle @@ -0,0 +1,73 @@ +plugins { + id "dev.kikugie.stonecutter" +} + +// The version whose code is uncommented in src/. Switch with "Set active project to ", and run +// "Reset active project" before committing. +stonecutter.active "1.21.11" + +subprojects { + apply plugin: "java" + + repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://git.selimaj.dev/api/packages/selimaj-dev/maven" } + maven { url "https://git.selimaj.dev/api/packages/saturnclientmc/maven" } + mavenCentral() + } + + dependencies { + implementation "de.javagl:obj:0.4.0" + implementation "com.formdev:svgSalamander:1.1.4" + implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0' + implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.0' + implementation 'com.fasterxml.jackson.core:jackson-core:2.17.0' + } +} + +configure(subprojects.findAll { it.name != "common" }) { + dependencies { + implementation project(":common") + } + + sourceSets { + main { + resources { + srcDir project(":common").file("src/main/resources") + } + } + } +} + +tasks.register("buildAll") { + group = "build" + description = "Builds all subprojects and collects their remapped jars" + + // Only build remapped jars (not full build) + dependsOn subprojects.collect { proj -> + proj.tasks.matching { it.name == "remapJar" } + } + + doLast { + def outputDir = file("$buildDir/allJars") + outputDir.mkdirs() + + subprojects.each { proj -> + def remapTask = proj.tasks.findByName("remapJar") + + if (remapTask != null) { + def jarFile = remapTask.archiveFile.get().asFile + + if (jarFile.exists() && !jarFile.name.contains("sources")) { + copy { + from jarFile + into outputDir + rename { "${jarFile.name}" } + } + } + } + } + + println "All remapped jars collected in: $outputDir" + } +} diff --git a/versions/1.21.11/build.gradle b/versions/1.21.11/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.11/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.11/settings.gradle b/versions/1.21.11/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.11/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file From eebfe8fa4db294480060f44daea4db28c62fa817 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 04:51:28 +0200 Subject: [PATCH 02/10] Switch the root build scripts to Kotlin and limit parallel remaps - settings.gradle, stonecutter.gradle and the root build.gradle become .kts. Loom's version for the Stonecutter versions moves to the root gradle.properties (loom_version), read by pluginManagement, since the Kotlin plugins block can't read properties. The old mc- projects keep their Groovy scripts until they're folded in. - buildAll ran all eight remapJar tasks at once. Each loads a Minecraft classpath and remaps a ~50 MB jar, which doesn't fit in the 3 GB daemon heap: a cold build stalled in garbage collection for 40+ minutes, and earlier runs failed. A shared build service now lets two remaps run together; a cold buildAll takes about 2 minutes. - port.sh and VERSION_GUIDE follow the .kts file names. The 1.21.11 jar is the same as with the Groovy scripts. Co-Authored-By: Claude Opus 5.5 --- VERSION_GUIDE.md | 8 +-- build.gradle | 101 ----------------------------- build.gradle.kts | 81 +++++++++++++++++++++++ gradle.properties | 3 + scripts/port.sh | 10 +-- settings.gradle | 40 ------------ settings.gradle.kts | 43 ++++++++++++ stonecutter.gradle | 73 --------------------- stonecutter.gradle.kts | 71 ++++++++++++++++++++ versions/1.21.11/gradle.properties | 1 - 10 files changed, 207 insertions(+), 224 deletions(-) delete mode 100644 build.gradle create mode 100644 build.gradle.kts delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts delete mode 100644 stonecutter.gradle create mode 100644 stonecutter.gradle.kts diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index e851152..444dd1f 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -10,11 +10,11 @@ Saturn is moving from one full copy of the version-specific code per Minecraft v - `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. - `versions//src/`: the versions not moved yet (1.21.4 to 1.21.10), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. -`settings.gradle` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle` builds each Stonecutter version, and `stonecutter.gradle` configures the root project (shared repositories, the `common` wiring and `buildAll`). +`settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. ## Version-specific code with Stonecutter -The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle`). Code for other versions sits in comments that Stonecutter swaps before building each version: +The code in `src/` is always plain Java for the **active** version (1.21.11, set in `stonecutter.gradle.kts`). Code for other versions sits in comments that Stonecutter swaps before building each version: ```java //? if >=1.21.9 { @@ -58,7 +58,7 @@ The **Check** workflow runs the same compile on every pull request, so a version Add new versions to Stonecutter rather than copying a folder: -1. Create `versions//gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at ). -2. Add `` to `stonecutterVersions` in `settings.gradle`. +1. Create `versions//gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at ). Loom's version is shared, in the root `gradle.properties`. +2. Add `` to `stonecutterVersions` in `settings.gradle.kts`. 3. Build it with `./gradlew ::compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew ::runClient`. 4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing. diff --git a/build.gradle b/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..5faa9c2 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,81 @@ +// Builds one Minecraft version from the shared src/. Stonecutter runs this for each version in +// stonecutterVersions (settings.gradle.kts), with that version's versions//gradle.properties. +plugins { + id("net.fabricmc.fabric-loom-remap") + `maven-publish` +} + +val minecraftVersion = property("minecraft_version") as String +val loaderVersion = property("loader_version") as String + +version = "${property("mod_version")}+$minecraftVersion" +group = property("maven_group") as String + +base { + archivesName = property("archives_base_name") as String +} + +dependencies { + minecraft("com.mojang:minecraft:$minecraftVersion") + mappings("net.fabricmc:yarn:${property("yarn_mappings")}:v2") + modImplementation("net.fabricmc:fabric-loader:$loaderVersion") + modImplementation("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}") + + // Saturn's emote library (limb bending, Emotecraft emotes) + include(modImplementation("org.saturnclient:emotes-fabric:${property("emotes_version")}+$minecraftVersion")!!) + + implementation(project(":common")) + + for (library in listOf( + "dev.selimaj:session-java:0.2.0", + "de.javagl:obj:0.4.0", + "com.formdev:svgSalamander:1.1.4", + "com.fasterxml.jackson.core:jackson-databind:2.17.0", + "com.fasterxml.jackson.core:jackson-annotations:2.17.0", + "com.fasterxml.jackson.core:jackson-core:2.17.0", + )) { + include(implementation(library)!!) + } +} + +// Injects the version values into fabric.mod.json. +tasks.processResources { + val values = mapOf( + "version" to project.version.toString(), + "minecraft_version" to minecraftVersion, + "loader_version" to loaderVersion, + ) + inputs.properties(values) + filteringCharset = "UTF-8" + filesMatching("fabric.mod.json") { expand(values) } +} + +tasks.withType().configureEach { + options.release = 21 +} + +java { + // Loom attaches the sources jar to remapSourcesJar and build. + withSourcesJar() + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + +tasks.jar { + val archivesName = base.archivesName + inputs.property("archivesName", archivesName) + from("LICENSE") { + rename { "${it}_${archivesName.get()}" } + } + from(project(":common").extensions.getByType()["main"].output) + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + +publishing { + publications { + create("mavenJava") { + artifactId = property("archives_base_name") as String + from(components["java"]) + } + } +} diff --git a/gradle.properties b/gradle.properties index a898428..947409b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,6 @@ mod_version=0.1.1-beta # Saturn's emote library (git.selimaj.dev/saturnclientmc/emotes) emotes_version=0.1.0 + +# Loom, for the Stonecutter versions (settings.gradle.kts). Old mc- projects set their own. +loom_version=1.17.21 diff --git a/scripts/port.sh b/scripts/port.sh index 5f22636..2715fd5 100755 --- a/scripts/port.sh +++ b/scripts/port.sh @@ -6,9 +6,9 @@ # normal merge conflicts only where a version really differs. Only source is # ported; build.gradle and gradle.properties are version-specific on purpose. # -# Versions moved to Stonecutter (stonecutterVersions in settings.gradle) share -# the top-level src/, which counts as one version: the active one set in -# stonecutter.gradle. The others keep their own copy in versions//src. +# Versions moved to Stonecutter (stonecutterVersions in settings.gradle.kts) +# share the top-level src/, which counts as one version: the active one set in +# stonecutter.gradle.kts. The others keep their own copy in versions//src. # # Usage: # scripts/port.sh [--from VERSION] [--to V1,V2,...] [--commit REV] [--dry-run] @@ -43,8 +43,8 @@ while [ $# -gt 0 ]; do done # Versions sharing the Stonecutter src/, and the one that stands for them. -stonecutter_versions=$(sed -n 's/^def stonecutterVersions = \[\(.*\)\]/\1/p' settings.gradle | tr -d '" ' | tr ',' ' ') -stonecutter_active=$(sed -n 's/^stonecutter\.active "\(.*\)"/\1/p' stonecutter.gradle 2>/dev/null || true) +stonecutter_versions=$(sed -n 's/^val stonecutterVersions = listOf(\(.*\))/\1/p' settings.gradle.kts | tr -d '" ' | tr ',' ' ') +stonecutter_active=$(sed -n 's/^stonecutter active "\(.*\)"/\1/p' stonecutter.gradle.kts 2>/dev/null || true) is_stonecutter() { printf '%s\n' $stonecutter_versions | grep -qx "$1" diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 95f2676..0000000 --- a/settings.gradle +++ /dev/null @@ -1,40 +0,0 @@ -pluginManagement { - repositories { - maven { url "https://maven.fabricmc.net/" } - maven { url "https://maven.kikugie.dev/releases" } - gradlePluginPortal() - mavenCentral() - } -} - -plugins { - id "dev.kikugie.stonecutter" version "0.9.8" -} - -rootProject.name = "saturn-client" - -include("common") - -// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle). Each one's -// versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -def stonecutterVersions = ["1.21.11"] - -stonecutter { - kotlinController = false // stonecutter.gradle configures the root project - centralScript = "build.gradle" // build.gradle configures each version - create(rootProject) { - versions(*stonecutterVersions) - vcsVersion = "1.21.11" - } -} - -// Versions not moved to Stonecutter yet still build from their own copy in versions//src, -// as projects named mc-. -file("versions").eachDir { dir -> - if (dir.name in stonecutterVersions) { - return - } - def projectName = "mc-${dir.name}" - include(projectName) - project(":${projectName}").projectDir = dir -} diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..69f2e22 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,43 @@ +pluginManagement { + repositories { + maven("https://maven.fabricmc.net/") + maven("https://maven.kikugie.dev/releases") + gradlePluginPortal() + mavenCentral() + } + + // Loom's version, for the Stonecutter versions' build.gradle.kts (the old mc- projects set + // their own in versions//gradle.properties). + val loom_version: String by settings + plugins { + id("net.fabricmc.fabric-loom-remap") version loom_version + } +} + +plugins { + id("dev.kikugie.stonecutter") version "0.9.8" +} + +rootProject.name = "saturn-client" + +include("common") + +// Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's +// versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. +val stonecutterVersions = listOf("1.21.11") + +stonecutter { + create(rootProject) { + versions(stonecutterVersions) + vcsVersion = "1.21.11" + } +} + +// Versions not moved to Stonecutter yet still build from their own copy in versions//src, +// as projects named mc-. +file("versions").listFiles { file -> file.isDirectory && file.name !in stonecutterVersions }!! + .sortedBy { it.name } + .forEach { dir -> + include("mc-${dir.name}") + project(":mc-${dir.name}").projectDir = dir + } diff --git a/stonecutter.gradle b/stonecutter.gradle deleted file mode 100644 index 131f357..0000000 --- a/stonecutter.gradle +++ /dev/null @@ -1,73 +0,0 @@ -plugins { - id "dev.kikugie.stonecutter" -} - -// The version whose code is uncommented in src/. Switch with "Set active project to ", and run -// "Reset active project" before committing. -stonecutter.active "1.21.11" - -subprojects { - apply plugin: "java" - - repositories { - maven { url "https://maven.fabricmc.net/" } - maven { url "https://git.selimaj.dev/api/packages/selimaj-dev/maven" } - maven { url "https://git.selimaj.dev/api/packages/saturnclientmc/maven" } - mavenCentral() - } - - dependencies { - implementation "de.javagl:obj:0.4.0" - implementation "com.formdev:svgSalamander:1.1.4" - implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.0' - implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.0' - implementation 'com.fasterxml.jackson.core:jackson-core:2.17.0' - } -} - -configure(subprojects.findAll { it.name != "common" }) { - dependencies { - implementation project(":common") - } - - sourceSets { - main { - resources { - srcDir project(":common").file("src/main/resources") - } - } - } -} - -tasks.register("buildAll") { - group = "build" - description = "Builds all subprojects and collects their remapped jars" - - // Only build remapped jars (not full build) - dependsOn subprojects.collect { proj -> - proj.tasks.matching { it.name == "remapJar" } - } - - doLast { - def outputDir = file("$buildDir/allJars") - outputDir.mkdirs() - - subprojects.each { proj -> - def remapTask = proj.tasks.findByName("remapJar") - - if (remapTask != null) { - def jarFile = remapTask.archiveFile.get().asFile - - if (jarFile.exists() && !jarFile.name.contains("sources")) { - copy { - from jarFile - into outputDir - rename { "${jarFile.name}" } - } - } - } - } - - println "All remapped jars collected in: $outputDir" - } -} diff --git a/stonecutter.gradle.kts b/stonecutter.gradle.kts new file mode 100644 index 0000000..ba6ec10 --- /dev/null +++ b/stonecutter.gradle.kts @@ -0,0 +1,71 @@ +plugins { + id("dev.kikugie.stonecutter") +} + +// The version whose code is uncommented in src/. Switch with "Set active project to ", and run +// "Reset active project" before committing. +stonecutter active "1.21.11" + +subprojects { + apply(plugin = "java") + + repositories { + maven("https://maven.fabricmc.net/") + maven("https://git.selimaj.dev/api/packages/selimaj-dev/maven") + maven("https://git.selimaj.dev/api/packages/saturnclientmc/maven") + mavenCentral() + } + + dependencies { + "implementation"("de.javagl:obj:0.4.0") + "implementation"("com.formdev:svgSalamander:1.1.4") + "implementation"("com.fasterxml.jackson.core:jackson-databind:2.17.0") + "implementation"("com.fasterxml.jackson.core:jackson-annotations:2.17.0") + "implementation"("com.fasterxml.jackson.core:jackson-core:2.17.0") + } +} + +// Every Minecraft version builds on common and ships its resources. +configure(subprojects.filter { it.name != "common" }) { + dependencies { + "implementation"(project(":common")) + } + + extensions.configure { + named("main") { + resources.srcDir(project(":common").file("src/main/resources")) + } + } +} + +// remapJar loads a whole Minecraft classpath and remaps a ~50 MB jar. Eight at once don't fit in the +// daemon's heap (org.gradle.jvmargs) and the build stalls in garbage collection, so only two run +// together. Everything else still builds in parallel. +abstract class RemapLimit : BuildService + +val remapLimit = gradle.sharedServices.registerIfAbsent("remapLimit", RemapLimit::class) { + maxParallelUsages = 2 +} + +subprojects { + tasks.matching { it.name == "remapJar" }.configureEach { + usesService(remapLimit) + } +} + +tasks.register("buildAll") { + group = "build" + description = "Builds every Minecraft version's remapped jar and collects them in build/allJars" + + val remapJars = subprojects.flatMap { it.tasks.matching { task -> task.name == "remapJar" } } + dependsOn(remapJars) + + doLast { + val outputDir = layout.buildDirectory.dir("allJars").get().asFile + outputDir.mkdirs() + remapJars.map { (it as AbstractArchiveTask).archiveFile.get().asFile } + .filter { it.exists() && !it.name.contains("sources") } + .forEach { it.copyTo(outputDir.resolve(it.name), overwrite = true) } + println("All remapped jars collected in: $outputDir") + } +} diff --git a/versions/1.21.11/gradle.properties b/versions/1.21.11/gradle.properties index ef10f0c..48f9b6d 100644 --- a/versions/1.21.11/gradle.properties +++ b/versions/1.21.11/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.11 yarn_mappings=1.21.11+build.4 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.141.3+1.21.11 From 95e4dff448d0e71abc09c4d51a68e03264c8726e Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 05:05:03 +0200 Subject: [PATCH 03/10] Build 1.21.10 with Stonecutter from the shared src/ Step 2 of #8. versions/1.21.10/src is gone; 1.21.10 builds from src/ as :1.21.10, with versions/1.21.10 keeping only gradle.properties and run/. API differences go behind version comments: render layers (ShaderUtils), Camera.update's World vs BlockView (CameraMixin), the text and textured-quad render states (RenderScopeImpl), Screen.init (SplashOverlayMixin) and jspecify's @NonNull (SaturnRenderState). Features 1.21.11 leaves out stay on 1.21.10, with a TODO for 1.21.11: WorldFeatureImpl.getWorldAge, SaturnScreenFabric.resize and EntityDrawerImpl clearing the hitbox. Hats now render on 1.21.10: its HatFeatureRenderer overrode the render-queue method with an empty body, and the working code sat in an old VertexConsumerProvider method nothing called. 1.21.10 now uses 1.21.11's render-queue implementation (HatFeatureRenderer, ObjModel, ObjRenderer), and also gets 1.21.11's null check on the player's display name. The 1.21.10 jar has the same entries, fabric.mod.json and mixin configs as before; only those four classes and ShaderUtils (a helper method for entityAlpha) have different bytecode. The 1.21.11 jar only differs in ShaderUtils. Co-Authored-By: Claude Opus 5.5 --- README.MD | 2 +- VERSION_GUIDE.md | 23 +- settings.gradle.kts | 2 +- .../impl/cosmetics/utils/ShaderUtils.java | 27 +- .../features/mixins/entity/CameraMixin.java | 6 + .../impl/features/world/WorldFeatureImpl.java | 5 +- .../impl/ui/EntityDrawerImpl.java | 3 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 8 + .../impl/ui/SaturnScreenFabric.java | 13 +- .../saturnclient/SaturnRenderState.java | 2 + .../mixin/SplashOverlayMixin.java | 5 + versions/1.21.10/build.gradle | 101 ---- versions/1.21.10/gradle.properties | 1 - versions/1.21.10/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 462 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 51 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 59 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 82 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------ .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 51 -- .../saturnclient/impl/mixins/TextMixin.java | 25 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ref/Matrix3x2fStackRef.java | 44 -- .../impl/ui/EntityDrawerImpl.java | 70 --- .../saturnclient/impl/ui/RenderScopeImpl.java | 347 ------------- .../impl/ui/SaturnScreenFabric.java | 140 ------ .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/SaturnRenderState.java | 10 - .../saturnclient/event/KeyInputHandler.java | 55 --- .../mixin/DrawContextAccessor.java | 12 - .../mixin/PlayerEntityRendererMixin.java | 61 --- .../saturnclient/mixin/SetScreenMixin.java | 27 - .../mixin/SplashOverlayMixin.java | 162 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 20 - .../src/main/resources/impl.mixins.json | 19 - .../main/resources/saturnclient.mixins.json | 17 - 66 files changed, 80 insertions(+), 3598 deletions(-) delete mode 100644 versions/1.21.10/build.gradle delete mode 100644 versions/1.21.10/settings.gradle delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.10/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.10/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.10/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.10/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index 578a3d2..30050ed 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.10) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.9) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index 444dd1f..cccbfe8 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.10), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.10 and 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.9), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -20,9 +20,24 @@ The code in `src/` is always plain Java for the **active** version (1.21.11, set //? if >=1.21.9 { public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { //?} else -/*public void render(MatrixStack matrices, VertexConsumerProvider consumers, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) {*/ +//public void render(MatrixStack matrices, VertexConsumerProvider consumers, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { ``` +A condition without braces covers the next line only. For several lines, use braces and wrap the inactive block in `/* … */`: + +```java +//? if >=1.21.11 { +import net.minecraft.client.render.RenderLayers; +import net.minecraft.client.render.RenderSetup; +//?} else { +/*import net.minecraft.client.render.RenderPhase.Textures; +*///?} +``` + +Stonecutter rewrites inactive code into its own layout when switching versions (a single inactive line becomes `//code`), so write it that way to begin with, or run a switch and a reset before committing. + +When a newer version leaves something out that an older one implements, keep the older version's code behind a condition and mark the newer branch with a `TODO`, rather than dropping it for every version. `WorldFeatureImpl.getWorldAge` and `SaturnScreenFabric.resize` are examples. + - `./gradlew "Set active project to "` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE. - `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active. - Each version's processed copy is compiled from `versions//build/generated/stonecutter/`, which is also where to look when a non-active version fails to compile. @@ -36,7 +51,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.9,1.21.10 # only some versions +scripts/port.sh --to 1.21.8,1.21.9 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` diff --git a/settings.gradle.kts b/settings.gradle.kts index 69f2e22..99e7a84 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.11") +val stonecutterVersions = listOf("1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java index 6dbb806..4935949 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java @@ -7,9 +7,14 @@ import com.mojang.blaze3d.pipeline.RenderPipeline; import net.minecraft.client.gl.RenderPipelines; import net.minecraft.client.render.RenderLayer; +//? if >=1.21.11 { import net.minecraft.client.render.RenderLayers; import net.minecraft.client.render.RenderSetup; import net.minecraft.client.render.block.entity.AbstractEndPortalBlockEntityRenderer; +//?} else { +/*import net.minecraft.client.render.RenderPhase.Textures; +import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; +*///?} import net.minecraft.util.Identifier; public class ShaderUtils { @@ -21,19 +26,35 @@ public class ShaderUtils { .withCull(false) .build()); + //? if >=1.21.11 { public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", RenderSetup.builder(END_GATEWAY_PIPELINE) .texture("Sampler0", AbstractEndPortalBlockEntityRenderer.SKY_TEXTURE) .texture("Sampler1", AbstractEndPortalBlockEntityRenderer.PORTAL_TEXTURE).build()); + //?} else { + /*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, + END_GATEWAY_PIPELINE, + RenderLayer.MultiPhaseParameters.builder() + .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) + .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) + .build(false)); + *///?} public static RenderLayer getRenderLayer(IdentifierRef texture) { String path = texture.toString(); if (path.endsWith(".gif")) { - return RenderLayers.entityAlpha((Identifier) (Object) GifUtils.get(texture)); + return entityAlpha((Identifier) (Object) GifUtils.get(texture)); } else if (path.endsWith("end.png")) { return END_GATEWAY; } else { - return RenderLayers.entityAlpha((Identifier) (Object) texture); + return entityAlpha((Identifier) (Object) texture); } } -} \ No newline at end of file + + private static RenderLayer entityAlpha(Identifier texture) { + //? if >=1.21.11 { + return RenderLayers.entityAlpha(texture); + //?} else + //return RenderLayer.getEntityAlpha(texture); + } +} diff --git a/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java index a335382..10b0630 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java @@ -13,7 +13,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.render.Camera; import net.minecraft.entity.Entity; +//? if >=1.21.11 { import net.minecraft.world.World; +//?} else +//import net.minecraft.world.BlockView; @Mixin(Camera.class) public abstract class CameraMixin { @@ -25,7 +28,10 @@ public abstract class CameraMixin { @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) public void lockRotation( + //? if >=1.21.11 { World focusedBlock, + //?} else + //BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, diff --git a/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java index bf84909..97facd1 100644 --- a/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ b/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java @@ -31,7 +31,10 @@ public class WorldFeatureImpl implements WorldFeature { */ @Override public long getWorldAge() { - // return hasWorld() ? mc.world.getTime() : 0L; + //? if >=1.21.11 { + // TODO: not implemented on 1.21.11 yet. return 0L; + //?} else + //return hasWorld() ? mc.world.getTime() : 0L; } } diff --git a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index ebdcf0a..073a8c7 100644 --- a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -62,7 +62,8 @@ public class EntityDrawerImpl implements EntityDrawer { EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - // entityRenderState.hitbox = null; + //? if <1.21.11 + //entityRenderState.hitbox = null; if (renderScope instanceof RenderScopeImpl i) i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); diff --git a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 5ba2ee7..613c813 100644 --- a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -34,6 +34,7 @@ import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.item.KeyedItemRenderState; +//? if >=1.21.11 import net.minecraft.client.texture.AbstractTexture; import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.TextureSetup; @@ -145,7 +146,10 @@ public class RenderScopeImpl implements RenderScope { ((Text) Fonts.setFont(line, font)).asOrderedText(), new Matrix3x2f(this.matrices.stack), 0, font == 0 ? 1 : 8, + //? if >=1.21.11 { finalColor, 0, false, false, this.scissorStack.peekLast())); + //?} else + //finalColor, 0, false, this.scissorStack.peekLast())); matrices.pop(); @@ -206,11 +210,15 @@ public class RenderScopeImpl implements RenderScope { GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() .getTexture(sprite).getGlTextureView(); + //? if >=1.21.11 AbstractTexture abstractTexture = SaturnClient.client.getTextureManager().getTexture(sprite); this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( RenderPipelines.GUI_TEXTURED, + //? if >=1.21.11 { TextureSetup.of(gpuTextureView, abstractTexture.getSampler()), + //?} else + //TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, u2, v1, v2, color, this.scissorStack.peekLast())); diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index eb77951..c6f57c9 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -116,11 +116,14 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { return super.keyPressed(input); } - // @Override - // public void resize(MinecraftClient client, int width, int height) { - // screen.resize(width, height); - // super.resize(client, width, height); - // } + // TODO: resize isn't hooked on 1.21.11 yet. + //? if <1.21.11 { + /*@Override + public void resize(MinecraftClient client, int width, int height) { + screen.resize(width, height); + super.resize(client, width, height); + } + *///?} @Override public void close() { diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java index 25faaff..ac57dcc 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java @@ -1,11 +1,13 @@ package org.saturnclient.saturnclient; +//? if >=1.21.11 import org.jspecify.annotations.NonNull; import org.saturnclient.client.player.SaturnPlayer; import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; public class SaturnRenderState { + //? if >=1.21.11 @NonNull public static RenderStateDataKey saturnDataKey = RenderStateDataKey .create(() -> "saturn-client-player"); diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java index daf1547..2ef9a6f 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java @@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.Final; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.SplashOverlay; +//? if >=1.21.11 import net.minecraft.client.util.Window; import net.minecraft.resource.ResourceReload; import net.minecraft.util.Util; @@ -155,9 +156,13 @@ public abstract class SplashOverlayMixin { reloadCompleteTime = Util.getMeasuringTimeMs(); + //? if >=1.21.11 Window window = client.getWindow(); if (client.currentScreen != null) { + //? if >=1.21.11 { client.currentScreen.init(window.getScaledWidth(), window.getScaledHeight()); + //?} else + //client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); } } } diff --git a/versions/1.21.10/build.gradle b/versions/1.21.10/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.10/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.10/gradle.properties b/versions/1.21.10/gradle.properties index 65a4a08..d153003 100644 --- a/versions/1.21.10/gradle.properties +++ b/versions/1.21.10/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.10 yarn_mappings=1.21.10+build.3 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.138.4+1.21.10 diff --git a/versions/1.21.10/settings.gradle b/versions/1.21.10/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.10/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index b13e942..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,462 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; -import org.saturnclient.saturnclient.SaturnRenderState; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - if (state.invisible || !state.capeVisible - || state.skinTextures.cape() != null) { - return; - } - - SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(state.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - matrices.push(); - - matrices.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(state.equippedChestStack, LayerType.HUMANOID)) { - matrices.translate(0.0F, -0.053125F, 0.06875F); - } - - if (state.isInSneakingPose) { - matrices.translate(0, 0.16f, 0.0f); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, state.field_53537 / 108.0f); - float rawVelY = state.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, state.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - final int l = light; - - horizontalCurve = MathHelper.clamp(state.field_53537 / 150.0f, -1.0f, 1.0f); - - queue.submitCustom(matrices, ShaderUtils.getRenderLayer(customCape), (entry, vertexConsumer) -> { - renderCape(entry, vertexConsumer, state, l, OverlayTexture.DEFAULT_UV); - }); - - matrices.pop(); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index 35110ec..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - // @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - if (state.displayName == null) - return; - - SaturnPlayer player = SaturnPlayer.get(state.displayName.getString()); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index c8cd2c2..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index bf6bc27..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().name(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().id(); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index 122ba6c..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.Identifier; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return null; - } - - @Override - public IdentifierRef getIconId() { - Identifier id = InGameHud.getEffectTexture(getEffectType()); - - return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png"); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 9ed634f..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.StyleSpriteSource.Font; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont(new Font((Identifier) (Object) font)))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index 3c58c85..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderManager; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b613ad4..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y, - this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 91d5a74..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.Click; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.input.KeyInput; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(Click click, boolean doubled) { - if (screen.mouseClicked(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseClicked(click, doubled); - } - - @Override - public boolean mouseDragged(Click click, double offsetX, double offsetY) { - if (screen.mouseDragged(click.x(), click.y(), click.button(), 0.0, 0.0)) { - return true; - } - - return super.mouseDragged(click, offsetX, offsetY); - } - - @Override - public boolean mouseReleased(Click click) { - if (screen.mouseReleased(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseReleased(click); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(KeyInput input) { - if (screen.keyPressed(input.getKeycode(), input.scancode(), input.modifiers())) { - return true; - } - - return super.keyPressed(input); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java deleted file mode 100644 index e34af31..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.saturnclient.saturnclient; - -import org.saturnclient.client.player.SaturnPlayer; - -import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; - -public class SaturnRenderState { - public static RenderStateDataKey saturnDataKey = RenderStateDataKey - .create(() -> "saturn-client-player"); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index f8ba756..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import net.minecraft.util.Identifier; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final Identifier KEY_CATEGORY = Identifier.of("saturnclient", "key.category.saturnclient"); - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding( - new KeyBinding( - MAIN_MENU_KEY_ID, - DEFAULT_MENU_KEY, - KeyBinding.Category.create(KEY_CATEGORY))); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 6da5ccb..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.ClientPlayerLikeEntity; -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.PlayerLikeEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -import org.saturnclient.saturnclient.SaturnRenderState; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } - - @Inject(method = "updateRenderState", at = @At("TAIL")) - public void updateRenderState( - A entity, PlayerEntityRenderState state, - float f, CallbackInfo ci) { - if (entity == null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(entity.getUuid()); - - state.setData(SaturnRenderState.saturnDataKey, player); - - if (player != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(player.uuid))); - - state.displayName = Text.empty() - .append(iconText.copy()) - .append(Text.empty().formatted(Formatting.RESET)) - .append(state.displayName.copy()); - } - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index cd463fd..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - // context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, - // Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 4dd9311..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.name(); - UUID uuid = profile.id(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.10/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.10/src/main/resources/fabric.mod.json b/versions/1.21.10/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.10/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.10/src/main/resources/features.mixins.json b/versions/1.21.10/src/main/resources/features.mixins.json deleted file mode 100644 index 4c74195..0000000 --- a/versions/1.21.10/src/main/resources/features.mixins.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.10/src/main/resources/impl.mixins.json b/versions/1.21.10/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.10/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.10/src/main/resources/saturnclient.mixins.json b/versions/1.21.10/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.10/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From f2d30e66111e7bcf7b0edf0da9c3757458469d76 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 05:10:15 +0200 Subject: [PATCH 04/10] Build 1.21.9 with Stonecutter from the shared src/ Step 3 of #8. 1.21.9's copy was identical to the old 1.21.10 one, so the existing version comments already cover it and no code changes: 1.21.9 is added to stonecutterVersions and versions/1.21.9/src is removed. Like 1.21.10 in step 2, 1.21.9 now renders hats (1.21.11's render-queue implementation) and gets the display-name null check. The jar has the same entries, fabric.mod.json and mixin configs as before; only those classes and ShaderUtils's entityAlpha helper differ in bytecode. Co-Authored-By: Claude Opus 5.5 --- README.MD | 2 +- VERSION_GUIDE.md | 6 +- settings.gradle.kts | 2 +- versions/1.21.9/build.gradle | 101 ---- versions/1.21.9/gradle.properties | 1 - versions/1.21.9/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 462 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 51 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 59 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 82 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------ .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 51 -- .../saturnclient/impl/mixins/TextMixin.java | 25 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ref/Matrix3x2fStackRef.java | 44 -- .../impl/ui/EntityDrawerImpl.java | 70 --- .../saturnclient/impl/ui/RenderScopeImpl.java | 347 ------------- .../impl/ui/SaturnScreenFabric.java | 140 ------ .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/SaturnRenderState.java | 10 - .../saturnclient/event/KeyInputHandler.java | 55 --- .../mixin/DrawContextAccessor.java | 12 - .../mixin/PlayerEntityRendererMixin.java | 61 --- .../saturnclient/mixin/SetScreenMixin.java | 27 - .../mixin/SplashOverlayMixin.java | 162 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.9/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 20 - .../src/main/resources/impl.mixins.json | 19 - .../main/resources/saturnclient.mixins.json | 17 - 58 files changed, 5 insertions(+), 3587 deletions(-) delete mode 100644 versions/1.21.9/build.gradle delete mode 100644 versions/1.21.9/settings.gradle delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.9/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.9/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.9/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.9/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index 30050ed..dcb50ac 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.9) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.8) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index cccbfe8..ac9d7ed 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.10 and 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.9), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.9 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.8), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -51,7 +51,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.8,1.21.9 # only some versions +scripts/port.sh --to 1.21.7,1.21.8 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` diff --git a/settings.gradle.kts b/settings.gradle.kts index 99e7a84..3f592e3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/versions/1.21.9/build.gradle b/versions/1.21.9/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.9/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.9/gradle.properties b/versions/1.21.9/gradle.properties index 5335436..7387155 100644 --- a/versions/1.21.9/gradle.properties +++ b/versions/1.21.9/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.9 yarn_mappings=1.21.9+build.1 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.134.1+1.21.9 diff --git a/versions/1.21.9/settings.gradle b/versions/1.21.9/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.9/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index b13e942..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,462 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; -import org.saturnclient.saturnclient.SaturnRenderState; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - if (state.invisible || !state.capeVisible - || state.skinTextures.cape() != null) { - return; - } - - SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(state.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - matrices.push(); - - matrices.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(state.equippedChestStack, LayerType.HUMANOID)) { - matrices.translate(0.0F, -0.053125F, 0.06875F); - } - - if (state.isInSneakingPose) { - matrices.translate(0, 0.16f, 0.0f); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, state.field_53537 / 108.0f); - float rawVelY = state.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, state.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - final int l = light; - - horizontalCurve = MathHelper.clamp(state.field_53537 / 150.0f, -1.0f, 1.0f); - - queue.submitCustom(matrices, ShaderUtils.getRenderLayer(customCape), (entry, vertexConsumer) -> { - renderCape(entry, vertexConsumer, state, l, OverlayTexture.DEFAULT_UV); - }); - - matrices.pop(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index 35110ec..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - // @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - if (state.displayName == null) - return; - - SaturnPlayer player = SaturnPlayer.get(state.displayName.getString()); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index c8cd2c2..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index bf6bc27..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().name(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().id(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index 122ba6c..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.Identifier; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return null; - } - - @Override - public IdentifierRef getIconId() { - Identifier id = InGameHud.getEffectTexture(getEffectType()); - - return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png"); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 9ed634f..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.StyleSpriteSource.Font; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont(new Font((Identifier) (Object) font)))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index 3c58c85..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderManager; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b613ad4..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y, - this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 91d5a74..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.Click; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.input.KeyInput; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(Click click, boolean doubled) { - if (screen.mouseClicked(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseClicked(click, doubled); - } - - @Override - public boolean mouseDragged(Click click, double offsetX, double offsetY) { - if (screen.mouseDragged(click.x(), click.y(), click.button(), 0.0, 0.0)) { - return true; - } - - return super.mouseDragged(click, offsetX, offsetY); - } - - @Override - public boolean mouseReleased(Click click) { - if (screen.mouseReleased(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseReleased(click); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(KeyInput input) { - if (screen.keyPressed(input.getKeycode(), input.scancode(), input.modifiers())) { - return true; - } - - return super.keyPressed(input); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java deleted file mode 100644 index e34af31..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.saturnclient.saturnclient; - -import org.saturnclient.client.player.SaturnPlayer; - -import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; - -public class SaturnRenderState { - public static RenderStateDataKey saturnDataKey = RenderStateDataKey - .create(() -> "saturn-client-player"); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index f8ba756..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import net.minecraft.util.Identifier; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final Identifier KEY_CATEGORY = Identifier.of("saturnclient", "key.category.saturnclient"); - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding( - new KeyBinding( - MAIN_MENU_KEY_ID, - DEFAULT_MENU_KEY, - KeyBinding.Category.create(KEY_CATEGORY))); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 6da5ccb..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.ClientPlayerLikeEntity; -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.PlayerLikeEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -import org.saturnclient.saturnclient.SaturnRenderState; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } - - @Inject(method = "updateRenderState", at = @At("TAIL")) - public
void updateRenderState( - A entity, PlayerEntityRenderState state, - float f, CallbackInfo ci) { - if (entity == null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(entity.getUuid()); - - state.setData(SaturnRenderState.saturnDataKey, player); - - if (player != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(player.uuid))); - - state.displayName = Text.empty() - .append(iconText.copy()) - .append(Text.empty().formatted(Formatting.RESET)) - .append(state.displayName.copy()); - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index cd463fd..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - // context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, - // Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 4dd9311..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.name(); - UUID uuid = profile.id(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/resources/fabric.mod.json b/versions/1.21.9/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.9/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.9/src/main/resources/features.mixins.json b/versions/1.21.9/src/main/resources/features.mixins.json deleted file mode 100644 index 4c74195..0000000 --- a/versions/1.21.9/src/main/resources/features.mixins.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.9/src/main/resources/impl.mixins.json b/versions/1.21.9/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.9/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.9/src/main/resources/saturnclient.mixins.json b/versions/1.21.9/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.9/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From 0bf4fc6808b30199f165cec9a28f52f414c86b67 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 05:24:24 +0200 Subject: [PATCH 05/10] Build 1.21.8 with Stonecutter from the shared src/ Step 4 of #8, the first version before the 1.21.9 render queue. versions/1.21.8/src is gone; 1.21.8 builds from src/ as :1.21.8. API differences behind version comments (<1.21.9 / >=1.21.9): - Player cosmetics: FeatureRenderer.render takes a VertexConsumerProvider instead of the render queue. The cloak, hat and OBJ renderers name the render target "output" in both, so only the parameter type and the final draw call differ; the OBJ face loop moved into drawGroup. - PlayerEntityRenderer.updateRenderState's entity type, the cape texture accessor, GameProfile getName()/getId() vs name()/id(), fonts in TextMixin, EntityRenderDispatcher vs EntityRenderManager, Screen input events (Click/KeyInput), and KeyBinding categories and isKeyPressed. Features 1.21.9+ lacks stay on 1.21.8, with a TODO for 1.21.9+: - NametagsMixin moves into src/. It hooks renderLabelIfPresent with a VertexConsumerProvider, which 1.21.9 changed, so on 1.21.9+ its body is empty; it stays registered, so features.mixins.json is the same for every version. - The splash screen's loading-bar border, and the real drag deltas in SaturnScreenFabric.mouseDragged. - Status effect icons keep 1.21.8's GUI atlas sprite; 1.21.9+ draws the texture instead (getIconId), as before. Behaviour changes on 1.21.8: the cloak and hat read the Saturn player from the render state (set by PlayerEntityRendererMixin, by UUID) instead of looking it up by name, and the display-name null check applies. Co-Authored-By: Claude Opus 5.5 --- README.MD | 2 +- VERSION_GUIDE.md | 12 +- settings.gradle.kts | 2 +- .../impl/cosmetics/CloakFeatureRenderer.java | 19 +- .../impl/cosmetics/HatFeatureRenderer.java | 13 +- .../impl/cosmetics/obj/ObjModel.java | 13 +- .../impl/cosmetics/obj/ObjRenderer.java | 34 +- .../features/mixins/misc/NametagsMixin.java | 14 +- .../render/LivingEntityRenderStateMixin.java | 1 + .../impl/mixins/MinecraftClientMixin.java | 6 + .../impl/mixins/StatusEffectMixin.java | 6 + .../saturnclient/impl/mixins/TextMixin.java | 4 + .../impl/ui/EntityDrawerImpl.java | 6 + .../impl/ui/SaturnScreenFabric.java | 40 ++ .../saturnclient/event/KeyInputHandler.java | 15 + .../mixin/PlayerEntityRendererMixin.java | 10 +- .../mixin/SplashOverlayMixin.java | 5 +- .../saturnclient/mixin/TabListMixin.java | 5 + src/main/resources/features.mixins.json | 1 + versions/1.21.8/build.gradle | 101 ---- versions/1.21.8/gradle.properties | 1 - versions/1.21.8/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 459 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 42 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 60 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 82 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------- .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 43 -- .../saturnclient/impl/mixins/TextMixin.java | 24 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ref/Matrix3x2fStackRef.java | 44 -- .../impl/ui/EntityDrawerImpl.java | 70 --- .../saturnclient/impl/ui/RenderScopeImpl.java | 347 ------------- .../impl/ui/SaturnScreenFabric.java | 134 ----- .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/SaturnRenderState.java | 10 - .../saturnclient/event/KeyInputHandler.java | 54 --- .../mixin/DrawContextAccessor.java | 12 - .../mixin/PlayerEntityRendererMixin.java | 60 --- .../saturnclient/mixin/SetScreenMixin.java | 27 -- .../mixin/SplashOverlayMixin.java | 161 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.8/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 21 - .../src/main/resources/impl.mixins.json | 19 - .../main/resources/saturnclient.mixins.json | 17 - 74 files changed, 175 insertions(+), 3587 deletions(-) rename {versions/1.21.8/src => src}/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java (88%) delete mode 100644 versions/1.21.8/build.gradle delete mode 100644 versions/1.21.8/settings.gradle delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.8/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.8/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.8/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.8/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index dcb50ac..730a837 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.8) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.7) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index ac9d7ed..3968256 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.9 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.8), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.8 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.7), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -36,7 +36,11 @@ import net.minecraft.client.render.RenderSetup; Stonecutter rewrites inactive code into its own layout when switching versions (a single inactive line becomes `//code`), so write it that way to begin with, or run a switch and a reset before committing. -When a newer version leaves something out that an older one implements, keep the older version's code behind a condition and mark the newer branch with a `TODO`, rather than dropping it for every version. `WorldFeatureImpl.getWorldAge` and `SaturnScreenFabric.resize` are examples. +When a newer version leaves something out that an older one implements, keep the older version's code behind a condition and mark the newer branch with a `TODO`, rather than dropping it for every version. `WorldFeatureImpl.getWorldAge` and `SaturnScreenFabric.resize` are examples. Search for `TODO` to find what newer versions still lack. + +A whole class that only exists for some versions (such as `NametagsMixin`, which hooks a method that 1.21.9 changed) can keep an empty class body on the other versions. An empty mixin changes nothing, and it keeps the mixin configs the same for every version, since JSON can't hold version comments. + +Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. - `./gradlew "Set active project to "` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE. - `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active. @@ -51,7 +55,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.7,1.21.8 # only some versions +scripts/port.sh --to 1.21.6,1.21.7 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` diff --git a/settings.gradle.kts b/settings.gradle.kts index 3f592e3..892053f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.9", "1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.8", "1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java index 8b3f462..6adbb50 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java @@ -15,7 +15,10 @@ import org.saturnclient.saturnclient.SaturnRenderState; import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.VertexConsumer; +//? if >=1.21.9 { import net.minecraft.client.render.command.OrderedRenderCommandQueue; +//?} else +//import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.equipment.EquipmentModel; import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; @@ -394,10 +397,17 @@ public class CloakFeatureRenderer extends FeatureRenderer=1.21.9 { + OrderedRenderCommandQueue output, + //?} else + //VertexConsumerProvider output, + int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { if (state.invisible || !state.capeVisible + //? if >=1.21.9 { || state.skinTextures.cape() != null) { + //?} else + //|| state.skinTextures.capeTexture() != null) { return; } @@ -454,9 +464,12 @@ public class CloakFeatureRenderer extends FeatureRenderer { + //? if >=1.21.9 { + output.submitCustom(matrices, ShaderUtils.getRenderLayer(customCape), (entry, vertexConsumer) -> { renderCape(entry, vertexConsumer, state, l, OverlayTexture.DEFAULT_UV); }); + //?} else + //renderCape(matrices.peek(), output.getBuffer(ShaderUtils.getRenderLayer(customCape)), state, l, OverlayTexture.DEFAULT_UV); matrices.pop(); } diff --git a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java index cdd6e50..9220d6e 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java @@ -7,7 +7,10 @@ import org.saturnclient.impl.cosmetics.obj.ObjModel; import org.saturnclient.saturnclient.SaturnRenderState; import net.minecraft.client.render.OverlayTexture; +//? if >=1.21.9 { import net.minecraft.client.render.command.OrderedRenderCommandQueue; +//?} else +//import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.model.PlayerEntityModel; @@ -21,8 +24,12 @@ public class HatFeatureRenderer extends FeatureRenderer=1.21.9 { + OrderedRenderCommandQueue output, + //?} else + //VertexConsumerProvider output, + int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); if (state.invisible || player == null || player.hat.isEmpty()) { @@ -35,7 +42,7 @@ public class HatFeatureRenderer extends FeatureRenderer=1.21.9 { import net.minecraft.client.render.command.OrderedRenderCommandQueue; +//?} else +//import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.resource.Resource; import net.minecraft.resource.ResourceManager; @@ -78,8 +81,12 @@ public class ObjModel { } } - public void render(Map mtlMap, MatrixStack matrices, OrderedRenderCommandQueue queue, int light, - int overlay) { + public void render(Map mtlMap, MatrixStack matrices, + //? if >=1.21.9 { + OrderedRenderCommandQueue output, + //?} else + //VertexConsumerProvider output, + int light, int overlay) { matrices.push(); matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); @@ -95,7 +102,7 @@ public class ObjModel { matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); } - ObjRenderer.renderObj(this.obj, mtlMap, matrices, queue, light, overlay); + ObjRenderer.renderObj(this.obj, mtlMap, matrices, output, light, overlay); matrices.pop(); } diff --git a/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java index 0914958..a4c7282 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java @@ -12,7 +12,10 @@ import de.javagl.obj.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; +//? if >=1.21.9 { import net.minecraft.client.render.command.OrderedRenderCommandQueue; +//?} else +//import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; @@ -28,7 +31,10 @@ public class ObjRenderer { public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - OrderedRenderCommandQueue queue, + //? if >=1.21.9 { + OrderedRenderCommandQueue output, + //?} else + //VertexConsumerProvider output, int light, int overlay) { @@ -64,19 +70,25 @@ public class ObjRenderer { final float fr = r, fg = g, fb = b; final Obj finalObj = groupObj; - queue.submitCustom(matrices, layer, (e, vertexConsumer) -> { + //? if >=1.21.9 { + output.submitCustom(matrices, layer, + (entry, consumer) -> drawGroup(finalObj, consumer, entry, light, overlay, fr, fg, fb)); + //?} else + //drawGroup(finalObj, output.getBuffer(layer), matrices.peek(), light, overlay, fr, fg, fb); + } + } - int faces = finalObj.getNumFaces(); + private static void drawGroup(Obj obj, VertexConsumer consumer, MatrixStack.Entry entry, int light, int overlay, + float r, float g, float b) { + int faces = obj.getNumFaces(); - for (int f = 0; f < faces; f++) { - ObjFace face = finalObj.getFace(f); - int verts = face.getNumVertices(); + for (int f = 0; f < faces; f++) { + ObjFace face = obj.getFace(f); + int verts = face.getNumVertices(); - for (int i = verts - 1; i >= 0; i--) { - writeVertex(finalObj, face, i, vertexConsumer, e, light, overlay, fr, fg, fb); - } - } - }); + for (int i = verts - 1; i >= 0; i--) { + writeVertex(obj, face, i, consumer, entry, light, overlay, r, g, b); + } } } diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java similarity index 88% rename from versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java rename to src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java index 8c1763d..be92969 100644 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java @@ -1,7 +1,9 @@ package org.saturnclient.impl.features.mixins.misc; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderer; +import org.spongepowered.asm.mixin.Mixin; +//? if <1.21.9 { +/*import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.util.math.MatrixStack; @@ -11,12 +13,12 @@ import org.saturnclient.impl.features.entity.EntityFeatureImpl; import org.saturnclient.impl.features.entity.HealthRenderState; import org.saturnclient.impl.features.mixins.render.LivingEntityRenderStateMixin; import org.saturnclient.mod.mods.NametagsMod; -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; +*///?} /** * Intercepts nametag rendering and replaces the displayed text with @@ -44,8 +46,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; */ @Mixin(EntityRenderer.class) public abstract class NametagsMixin { - - /** Guards against the recursive call we make with the replacement text. */ + // TODO: 1.21.9 moved label rendering to the render queue (renderLabelIfPresent no longer takes a + // VertexConsumerProvider), so custom nametags only work on older versions. On 1.21.9+ this mixin is + // empty but stays registered, so features.mixins.json is the same for every version. + //? if <1.21.9 { + /*// Guards against the recursive call we make with the replacement text. @Unique private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); @@ -92,4 +97,5 @@ public abstract class NametagsMixin { saturn$rendering.set(false); } } + *///?} } diff --git a/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java index c8cd2c2..bbb293b 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java @@ -4,6 +4,7 @@ import net.minecraft.client.render.entity.state.LivingEntityRenderState; import org.saturnclient.common.feature.EntityFeature; import org.saturnclient.impl.features.entity.HealthRenderState; +import org.saturnclient.impl.features.mixins.misc.NametagsMixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java index bf6bc27..1aeb6f8 100644 --- a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java @@ -141,7 +141,10 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { if (entry == null) return null; + //? if >=1.21.9 { return entry.getProfile().name(); + //?} else + //return entry.getProfile().getName(); } @Override @@ -157,6 +160,9 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { if (entry == null) return null; + //? if >=1.21.9 { return entry.getProfile().id(); + //?} else + //return entry.getProfile().getId(); } } diff --git a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java index 122ba6c..4977a40 100644 --- a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java @@ -3,6 +3,8 @@ package org.saturnclient.impl.mixins; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.common.ref.asset.SpriteRef; import org.saturnclient.common.ref.game.EffectRef; +//? if <1.21.9 +//import org.saturnclient.saturnclient.SaturnClient; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -29,7 +31,11 @@ public abstract class StatusEffectMixin implements EffectRef { @Override public SpriteRef getIcon() { + // 1.21.9 changed the GUI atlas, so newer versions draw the effect's texture (getIconId) instead. + //? if >=1.21.9 { return null; + //?} else + //return (SpriteRef) SaturnClient.client.getGuiAtlasManager().getSprite((InGameHud.getEffectTexture(getEffectType()))); } @Override diff --git a/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/src/main/java/org/saturnclient/impl/mixins/TextMixin.java index e2fdf55..e5e31f6 100644 --- a/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/TextMixin.java @@ -7,6 +7,7 @@ import org.spongepowered.asm.mixin.Mixin; import net.minecraft.text.Style; import net.minecraft.text.Text; +//? if >=1.21.9 import net.minecraft.text.StyleSpriteSource.Font; import net.minecraft.util.Identifier; @@ -15,7 +16,10 @@ public interface TextMixin extends TextRef { @Override public default TextRef withFont(IdentifierRef font) { + //? if >=1.21.9 { return (TextRef) (Text) (((Text) this).copy().setStyle(Style.EMPTY.withFont(new Font((Identifier) (Object) font)))); + //?} else + //return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); } @Override diff --git a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index 073a8c7..31761ce 100644 --- a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -8,7 +8,10 @@ import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; import org.saturnclient.ui.components.SkinPreview.EntityDrawer; +//? if >=1.21.9 { import net.minecraft.client.render.entity.EntityRenderManager; +//?} else +//import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderer; import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.entity.LivingEntity; @@ -59,7 +62,10 @@ public class EntityDrawerImpl implements EntityDrawer { public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, LivingEntity entity) { + //? if >=1.21.9 { EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + //?} else + //EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); //? if <1.21.11 diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index c6f57c9..38c3619 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -8,11 +8,13 @@ import org.saturnclient.ui.SaturnScreen; import org.saturnclient.ui.SaturnScreen.ScreenProvider; import net.minecraft.client.MinecraftClient; +//? if >=1.21.9 import net.minecraft.client.gui.Click; import net.minecraft.client.gui.CubeMapRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.RotatingCubeMapRenderer; import net.minecraft.client.gui.screen.Screen; +//? if >=1.21.9 import net.minecraft.client.input.KeyInput; import net.minecraft.client.texture.ResourceTexture; import net.minecraft.client.texture.TextureManager; @@ -72,6 +74,8 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { screen.render(renderScope, mouseX, mouseY, delta, elapsed); } + // 1.21.9 moved mouse and key events to Click and KeyInput. + //? if >=1.21.9 { @Override public boolean mouseClicked(Click click, boolean doubled) { if (screen.mouseClicked(click.x(), click.y(), click.button())) { @@ -83,6 +87,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { @Override public boolean mouseDragged(Click click, double offsetX, double offsetY) { + // TODO: 1.21.8 passes the drag deltas; check whether offsetX/offsetY are the same on 1.21.9+. if (screen.mouseDragged(click.x(), click.y(), click.button(), 0.0, 0.0)) { return true; } @@ -98,6 +103,31 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { return super.mouseReleased(click); } + //?} else { + /*@Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (screen.mouseClicked(mouseX, mouseY, button)) { + return true; + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { + return true; + } + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (screen.mouseReleased(mouseX, mouseY, button)) { + return true; + } + return super.mouseReleased(mouseX, mouseY, button); + } + *///?} @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { @@ -107,6 +137,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } + //? if >=1.21.9 { @Override public boolean keyPressed(KeyInput input) { if (screen.keyPressed(input.getKeycode(), input.scancode(), input.modifiers())) { @@ -115,6 +146,15 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { return super.keyPressed(input); } + //?} else { + /*@Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (screen.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + *///?} // TODO: resize isn't hooked on 1.21.11 yet. //? if <1.21.11 { diff --git a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index f8ba756..adecfba 100644 --- a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -4,6 +4,7 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; +//? if >=1.21.9 import net.minecraft.util.Identifier; import org.saturnclient.config.Config; @@ -21,17 +22,28 @@ import org.lwjgl.glfw.GLFW; * Manages keybindings and their associated actions. */ public class KeyInputHandler { + //? if >=1.21.9 { private static final Identifier KEY_CATEGORY = Identifier.of("saturnclient", "key.category.saturnclient"); + //?} else + //private static final String KEY_CATEGORY = "key.category.saturnclient"; private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; private static KeyBinding mainMenuKeyBinding; public static void register() { + //? if >=1.21.9 { mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding( new KeyBinding( MAIN_MENU_KEY_ID, DEFAULT_MENU_KEY, KeyBinding.Category.create(KEY_CATEGORY))); + //?} else { + /*mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( + MAIN_MENU_KEY_ID, + InputUtil.Type.KEYSYM, + DEFAULT_MENU_KEY, + KEY_CATEGORY)); + *///?} // Register the event handler for the main menu key ClientTickEvents.END_CLIENT_TICK.register(client -> { @@ -40,7 +52,10 @@ public class KeyInputHandler { } if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null + //? if >=1.21.9 { && !InputUtil.isKeyPressed(client.getWindow(), GLFW.GLFW_KEY_F3)) { + //?} else + //&& !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { Providers.saturn.getClient().setScreen(new EmoteWheel()); } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java index f165cfc..bae4933 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java @@ -1,12 +1,15 @@ package org.saturnclient.saturnclient.mixin; +//? if >=1.21.9 { import net.minecraft.client.network.ClientPlayerLikeEntity; +import net.minecraft.entity.PlayerLikeEntity; +//?} else +//import net.minecraft.client.network.AbstractClientPlayerEntity; 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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.PlayerLikeEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.text.MutableText; import net.minecraft.text.Text; @@ -37,8 +40,13 @@ public abstract class PlayerEntityRendererMixin } @Inject(method = "updateRenderState", at = @At("TAIL")) + //? if >=1.21.9 { public void updateRenderState( A entity, PlayerEntityRenderState state, + //?} else { + /*public void updateRenderState( + AbstractClientPlayerEntity entity, PlayerEntityRenderState state, + *///?} float f, CallbackInfo ci) { if (entity == null) { return; diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java index 2ef9a6f..545063d 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java @@ -126,8 +126,9 @@ public abstract class SplashOverlayMixin { private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, int alpha) { int progressY = ((screenHeight - 5) / 2) + 25; - // context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, - // Theme.withAlpha(alpha, 0xFFFFFFFF)); + // TODO: the loading bar's border isn't drawn on 1.21.9+ yet. + //? if <1.21.9 + //context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); int progressWidth = Math.min((int) (progress * 120), 120); int progressX = (screenWidth - 120) / 2; diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java index 4dd9311..b76385b 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java @@ -27,8 +27,13 @@ public abstract class TabListMixin { private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { PlayerListEntry entry = (PlayerListEntry) (Object) this; GameProfile profile = entry.getProfile(); + //? if >=1.21.9 { String name = profile.name(); UUID uuid = profile.id(); + //?} else { + /*String name = profile.getName(); + UUID uuid = profile.getId(); + *///?} if (SaturnPlayer.get(name, uuid) == null) { return; diff --git a/src/main/resources/features.mixins.json b/src/main/resources/features.mixins.json index 4c74195..8d3c331 100644 --- a/src/main/resources/features.mixins.json +++ b/src/main/resources/features.mixins.json @@ -9,6 +9,7 @@ "render.LivingEntityRendererMixin", "render.LivingEntityRenderStateMixin", "render.BackgroundRendererMixin", + "misc.NametagsMixin", "render.RenderMixin", "world.TpsMixin", "entity.CameraMixin", diff --git a/versions/1.21.8/build.gradle b/versions/1.21.8/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.8/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.8/gradle.properties b/versions/1.21.8/gradle.properties index 991192a..515654b 100644 --- a/versions/1.21.8/gradle.properties +++ b/versions/1.21.8/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.8 yarn_mappings=1.21.8+build.1 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.136.1+1.21.8 diff --git a/versions/1.21.8/settings.gradle b/versions/1.21.8/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.8/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index 2725e32..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, - PlayerEntityRenderState playerEntityRenderState, float f, float g) { - if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible - || playerEntityRenderState.skinTextures.capeTexture() != null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(ShaderUtils.getRenderLayer(customCape)); - - matrixStack.push(); - - matrixStack.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { - matrixStack.translate(0.0F, -0.053125F, 0.06875F); - } - - if (playerEntityRenderState.isInSneakingPose) { - matrixStack.translate(0, 0.16f, 0.0f); - matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, playerEntityRenderState.field_53537 / 108.0f); - float rawVelY = playerEntityRenderState.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, playerEntityRenderState.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - horizontalCurve = MathHelper.clamp(playerEntityRenderState.field_53537 / 150.0f, -1.0f, 1.0f); - - renderCape(matrixStack.peek(), vertexConsumer, playerEntityRenderState, light, OverlayTexture.DEFAULT_UV); - - matrixStack.pop(); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index cce3ec2..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - SaturnPlayer player = SaturnPlayer.get(state.name); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index bbb293b..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.misc.NametagsMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index b0a269a..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().getName(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().getId(); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index df9ad35..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return (SpriteRef) SaturnClient.client.getGuiAtlasManager().getSprite((InGameHud.getEffectTexture(getEffectType()))); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 3e1a8b8..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index c2bfe84..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b613ad4..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y, - this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 3717c6f..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (screen.mouseClicked(mouseX, mouseY, button)) { - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { - return true; - } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (screen.mouseReleased(mouseX, mouseY, button)) { - return true; - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (screen.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java deleted file mode 100644 index e34af31..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.saturnclient.saturnclient; - -import org.saturnclient.client.player.SaturnPlayer; - -import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; - -public class SaturnRenderState { - public static RenderStateDataKey saturnDataKey = RenderStateDataKey - .create(() -> "saturn-client-player"); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index 7424639..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final String KEY_CATEGORY = "key.category.saturnclient"; - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - MAIN_MENU_KEY_ID, - InputUtil.Type.KEYSYM, - DEFAULT_MENU_KEY, - KEY_CATEGORY)); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 5a22bbb..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.AbstractClientPlayerEntity; -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -import org.saturnclient.saturnclient.SaturnRenderState; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } - - @Inject(method = "updateRenderState", at = @At("TAIL")) - public void updateRenderState( - AbstractClientPlayerEntity entity, PlayerEntityRenderState state, - float f, CallbackInfo ci) { - if (entity == null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(entity.getUuid()); - - state.setData(SaturnRenderState.saturnDataKey, player); - - if (player != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(player.uuid))); - - state.displayName = Text.empty() - .append(iconText.copy()) - .append(Text.empty().formatted(Formatting.RESET)) - .append(state.displayName.copy()); - } - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index ecc4823..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 2a68cd6..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.getName(); - UUID uuid = profile.getId(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.8/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.8/src/main/resources/fabric.mod.json b/versions/1.21.8/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.8/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.8/src/main/resources/features.mixins.json b/versions/1.21.8/src/main/resources/features.mixins.json deleted file mode 100644 index 8d3c331..0000000 --- a/versions/1.21.8/src/main/resources/features.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "misc.NametagsMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.8/src/main/resources/impl.mixins.json b/versions/1.21.8/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.8/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.8/src/main/resources/saturnclient.mixins.json b/versions/1.21.8/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.8/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From 6f122b5237d59bfc551ad60111634d85b5fb566f Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 05:46:41 +0200 Subject: [PATCH 06/10] Build 1.21.7 with Stonecutter from the shared src/ Step 5 of #8. versions/1.21.7/src is gone; 1.21.7 builds from src/ as :1.21.7. 1.21.7's copy differed from 1.21.8's in the player render state: Fabric API's RenderStateDataKey only exists from 1.21.8 (fabric-rendering-v1 12.6.0), so 1.21.7 had no updateRenderState hook, no SaturnRenderState, and looked players up by name for the cloak and hat. That stays the case: - The cloak and hat use getData on >=1.21.8 and SaturnPlayer.get(name) before that. - PlayerEntityRendererMixin's updateRenderState exists only on >=1.21.8, as flat ranges (>=1.21.9, else if >=1.21.8) calling a shared saturn$applyPlayer helper, instead of nested version blocks. - SaturnRenderState's key only exists on >=1.21.8; the class is empty before. - TODO: 1.21.6 and 1.21.7 still don't show the role icon in names. 1.21.7's NameTagMixin isn't carried over: it wasn't registered in any mixin config, so it never ran. The 1.21.7 jar differs from the old one only as 1.21.8's did in step 4 (entityAlpha and drawGroup helpers, getIconId, and the cloak getting its buffer at the draw call), plus the empty SaturnRenderState and the missing dead NameTagMixin. 1.21.8-1.21.11 only differ in PlayerEntityRendererMixin (the helper). Co-Authored-By: Claude Opus 5.5 --- README.MD | 2 +- VERSION_GUIDE.md | 8 +- settings.gradle.kts | 2 +- .../impl/cosmetics/CloakFeatureRenderer.java | 3 + .../impl/cosmetics/HatFeatureRenderer.java | 3 + .../saturnclient/SaturnRenderState.java | 12 +- .../mixin/PlayerEntityRendererMixin.java | 24 +- versions/1.21.7/build.gradle | 101 ---- versions/1.21.7/gradle.properties | 1 - versions/1.21.7/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 459 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 42 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../features/mixins/misc/NametagsMixin.java | 95 ---- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 60 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 82 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------- .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 43 -- .../saturnclient/impl/mixins/TextMixin.java | 24 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ref/Matrix3x2fStackRef.java | 44 -- .../impl/ui/EntityDrawerImpl.java | 70 --- .../saturnclient/impl/ui/RenderScopeImpl.java | 347 ------------- .../impl/ui/SaturnScreenFabric.java | 134 ----- .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/event/KeyInputHandler.java | 54 --- .../mixin/DrawContextAccessor.java | 12 - .../saturnclient/mixin/NameTagMixin.java | 93 ---- .../mixin/PlayerEntityRendererMixin.java | 30 -- .../saturnclient/mixin/SetScreenMixin.java | 27 -- .../mixin/SplashOverlayMixin.java | 161 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.7/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 21 - .../src/main/resources/impl.mixins.json | 19 - .../main/resources/saturnclient.mixins.json | 17 - 63 files changed, 41 insertions(+), 3715 deletions(-) delete mode 100644 versions/1.21.7/build.gradle delete mode 100644 versions/1.21.7/settings.gradle delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.7/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.7/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.7/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.7/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index 730a837..f40ffcf 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.7) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.6) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index 3968256..1bdc62a 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.8 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.7), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.7 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.6), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -40,7 +40,7 @@ When a newer version leaves something out that an older one implements, keep the A whole class that only exists for some versions (such as `NametagsMixin`, which hooks a method that 1.21.9 changed) can keep an empty class body on the other versions. An empty mixin changes nothing, and it keeps the mixin configs the same for every version, since JSON can't hold version comments. -Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. +Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. For the same reason, don't nest multi-line version blocks; use `//?} else if {` for more than two version ranges, as in `PlayerEntityRendererMixin` and `SaturnRenderState`. - `./gradlew "Set active project to "` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE. - `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active. @@ -55,7 +55,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.6,1.21.7 # only some versions +scripts/port.sh --to 1.21.5,1.21.6 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` diff --git a/settings.gradle.kts b/settings.gradle.kts index 892053f..0df4901 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.8", "1.21.9", "1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java index 6adbb50..046f3b0 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java @@ -411,7 +411,10 @@ public class CloakFeatureRenderer extends FeatureRenderer=1.21.8 { SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); + //?} else + //SaturnPlayer player = SaturnPlayer.get(state.name); if (player == null) { return; diff --git a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java index 9220d6e..9891052 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java @@ -30,7 +30,10 @@ public class HatFeatureRenderer extends FeatureRenderer=1.21.8 { SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); + //?} else + //SaturnPlayer player = SaturnPlayer.get(state.name); if (state.invisible || player == null || player.hat.isEmpty()) { return; diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java index ac57dcc..777b53b 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java @@ -2,13 +2,23 @@ package org.saturnclient.saturnclient; //? if >=1.21.11 import org.jspecify.annotations.NonNull; +//? if >=1.21.8 { import org.saturnclient.client.player.SaturnPlayer; import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; +//?} +/** + * The key PlayerEntityRendererMixin stores each player's SaturnPlayer under in their render state. + * Fabric API's render state data only exists from 1.21.8, so older versions look players up by name. + */ public class SaturnRenderState { - //? if >=1.21.11 + //? if >=1.21.11 { @NonNull public static RenderStateDataKey saturnDataKey = RenderStateDataKey .create(() -> "saturn-client-player"); + //?} else if >=1.21.8 { + /*public static RenderStateDataKey saturnDataKey = RenderStateDataKey + .create(() -> "saturn-client-player"); + *///?} } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java index bae4933..e02da40 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java @@ -10,6 +10,7 @@ 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.render.entity.state.PlayerEntityRenderState; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.text.MutableText; import net.minecraft.text.Text; @@ -39,15 +40,25 @@ public abstract class PlayerEntityRendererMixin this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); } - @Inject(method = "updateRenderState", at = @At("TAIL")) + // Stores the SaturnPlayer in the render state and adds the role icon to the name. Render state + // data only exists from 1.21.8. + // TODO: 1.21.6 and 1.21.7 don't show the role icon in player names. //? if >=1.21.9 { + @Inject(method = "updateRenderState", at = @At("TAIL")) public
void updateRenderState( - A entity, PlayerEntityRenderState state, - //?} else { - /*public void updateRenderState( - AbstractClientPlayerEntity entity, PlayerEntityRenderState state, + A entity, PlayerEntityRenderState state, float f, CallbackInfo ci) { + saturn$applyPlayer(entity, state); + } + //?} else if >=1.21.8 { + /*@Inject(method = "updateRenderState", at = @At("TAIL")) + public void updateRenderState( + AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float f, CallbackInfo ci) { + saturn$applyPlayer(entity, state); + } *///?} - float f, CallbackInfo ci) { + + //? if >=1.21.8 { + private void saturn$applyPlayer(Entity entity, PlayerEntityRenderState state) { if (entity == null) { return; } @@ -66,4 +77,5 @@ public abstract class PlayerEntityRendererMixin .append(state.displayName.copy()); } } + //?} } \ No newline at end of file diff --git a/versions/1.21.7/build.gradle b/versions/1.21.7/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.7/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.7/gradle.properties b/versions/1.21.7/gradle.properties index 1932513..53d8f2e 100644 --- a/versions/1.21.7/gradle.properties +++ b/versions/1.21.7/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.7 yarn_mappings=1.21.7+build.8 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.129.0+1.21.7 diff --git a/versions/1.21.7/settings.gradle b/versions/1.21.7/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.7/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index 2725e32..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, - PlayerEntityRenderState playerEntityRenderState, float f, float g) { - if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible - || playerEntityRenderState.skinTextures.capeTexture() != null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(ShaderUtils.getRenderLayer(customCape)); - - matrixStack.push(); - - matrixStack.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { - matrixStack.translate(0.0F, -0.053125F, 0.06875F); - } - - if (playerEntityRenderState.isInSneakingPose) { - matrixStack.translate(0, 0.16f, 0.0f); - matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, playerEntityRenderState.field_53537 / 108.0f); - float rawVelY = playerEntityRenderState.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, playerEntityRenderState.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - horizontalCurve = MathHelper.clamp(playerEntityRenderState.field_53537 / 150.0f, -1.0f, 1.0f); - - renderCape(matrixStack.peek(), vertexConsumer, playerEntityRenderState, light, OverlayTexture.DEFAULT_UV); - - matrixStack.pop(); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index cce3ec2..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - SaturnPlayer player = SaturnPlayer.get(state.name); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java deleted file mode 100644 index 8c1763d..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.saturnclient.impl.features.mixins.misc; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; - -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.render.LivingEntityRenderStateMixin; -import org.saturnclient.mod.mods.NametagsMod; -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; - -/** - * Intercepts nametag rendering and replaces the displayed text with - * the string produced by {@link NametagsMod#getNametagString}. - * - * Key changes from the original: - * - *
    - *
  • The old {@code NametagsFabric.EntityStateImpl} bridge class is - * replaced by {@link EntityFeatureImpl.RenderStateEntityState}, - * which wraps the {@link HealthRenderState} already injected into - * the render state by {@link LivingEntityRenderStateMixin}.
  • - *
  • The feature import changes from {@code Nametags} to - * {@link NametagsMod}; the two static methods - * ({@code shouldReplaceName} / {@code getNametagString}) are - * unchanged in signature.
  • - *
  • The entity's display name is extracted from the render state's - * {@code nameVisible} / text fields where available, falling back - * to the plain text string passed to this method.
  • - *
- * - * The re-entrancy guard ({@code saturn$rendering}) is kept intact to - * prevent infinite recursion when we call {@code renderLabelIfPresent} - * with the replacement text. - */ -@Mixin(EntityRenderer.class) -public abstract class NametagsMixin { - - /** Guards against the recursive call we make with the replacement text. */ - @Unique - private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); - - @Shadow - protected abstract void renderLabelIfPresent( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void saturn$replaceNametag( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - - // Skip our own recursive call - if (saturn$rendering.get()) - return; - - if (!NametagsMod.shouldReplaceName()) - return; - - // Only living entities carry health data - if (!(state instanceof LivingEntityRenderState living)) - return; - if (!(living instanceof HealthRenderState hrs)) - return; - - // Build the platform-neutral EntityState from the render-state snapshot - // (health/type were written by LivingEntityRendererMixin at extract time). - String customName = text != null ? text.getString() : null; - EntityFeatureImpl.RenderStateEntityState entityState = new EntityFeatureImpl.RenderStateEntityState( - customName, hrs); - - // Ask the feature for the replacement string - String replacement = NametagsMod.getNametagString(entityState); - if (replacement == null) - return; // feature decided not to replace this entity - - ci.cancel(); - saturn$rendering.set(true); - try { - renderLabelIfPresent(state, Text.literal(replacement), matrices, vertexConsumers, light); - } finally { - saturn$rendering.set(false); - } - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index bbb293b..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.misc.NametagsMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index b0a269a..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().getName(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().getId(); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index df9ad35..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return (SpriteRef) SaturnClient.client.getGuiAtlasManager().getSprite((InGameHud.getEffectTexture(getEffectType()))); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 3e1a8b8..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index c2bfe84..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b613ad4..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y, - this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 3717c6f..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (screen.mouseClicked(mouseX, mouseY, button)) { - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { - return true; - } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (screen.mouseReleased(mouseX, mouseY, button)) { - return true; - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (screen.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index 7424639..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final String KEY_CATEGORY = "key.category.saturnclient"; - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - MAIN_MENU_KEY_ID, - InputUtil.Type.KEYSYM, - DEFAULT_MENU_KEY, - KEY_CATEGORY)); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java deleted file mode 100644 index 518494c..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec3d; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.saturnclient.SaturnClient; - -import java.util.UUID; - -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(value = EntityRenderer.class, priority = 1800) -public abstract class NameTagMixin { - @Shadow - public EntityRenderDispatcher dispatcher; - - /** - * @author HexLeo - * @reason Adds the Saturn Client icon to the player's name if they are online - * with Saturn Client - */ - @Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true) - private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - - UUID uuid = isSaturn(state); - - if (uuid != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid))); - - Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); - - renderLabel(state, iconText.append(nameText), matrices, - vertexConsumers, light); - - ci.cancel(); - } - } - - private UUID isSaturn(S state) { - if (state instanceof PlayerEntityRenderState) { - String name = ((PlayerEntityRenderState) state).name; - SaturnPlayer player = SaturnPlayer.get(name); - if (player != null) { - return player.uuid; - } - } - - return null; - } - - private void renderLabel(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light) { - Vec3d vec3d = state.nameLabelPos; - if (vec3d != null) { - boolean bl = !state.sneaking; - int i = "deadmau5".equals(text.getString()) ? -10 : 0; - matrices.push(); - matrices.translate(vec3d.x, vec3d.y + 0.5, vec3d.z); - matrices.multiply(this.dispatcher.getRotation()); - matrices.scale(0.025F, -0.025F, 0.025F); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - float f = (float) (-textRenderer.getWidth(text)) / 2.0F; - int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; - textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers, - bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light); - if (bl) { - textRenderer.draw(text, f, (float) i, -1, false, matrix4f, vertexConsumers, TextLayerType.NORMAL, 0, - light); - } - matrices.pop(); - } - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 0363dad..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index ecc4823..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 2a68cd6..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.getName(); - UUID uuid = profile.getId(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.7/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.7/src/main/resources/fabric.mod.json b/versions/1.21.7/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.7/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.7/src/main/resources/features.mixins.json b/versions/1.21.7/src/main/resources/features.mixins.json deleted file mode 100644 index 8d3c331..0000000 --- a/versions/1.21.7/src/main/resources/features.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "misc.NametagsMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.7/src/main/resources/impl.mixins.json b/versions/1.21.7/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.7/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.7/src/main/resources/saturnclient.mixins.json b/versions/1.21.7/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.7/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From a949c18ec19d7b5662e3c9e89e9637e59892244b Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 06:10:31 +0200 Subject: [PATCH 07/10] Build 1.21.6 with Stonecutter from the shared src/ 1.21.6's copy only differed from 1.21.7's in RenderScopeImpl: item rendering uses ItemRenderState, which 1.21.7 renamed to KeyedItemRenderState. That's behind a version comment; 1.21.6 keeps its older loader_version (0.18.5) in its gradle.properties. Moving a version over leaves the old mc- project's compiled classes in the shared build/ folder, so a removed class (1.21.6's dead NameTagMixin) still got packaged until a clean. VERSION_GUIDE now says to run ::clean once after moving a version. Co-Authored-By: Claude Opus 5.5 --- README.MD | 2 +- VERSION_GUIDE.md | 8 +- settings.gradle.kts | 2 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 6 + versions/1.21.6/build.gradle | 101 ---- versions/1.21.6/gradle.properties | 1 - versions/1.21.6/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 459 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 42 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../features/mixins/misc/NametagsMixin.java | 95 ---- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 60 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 82 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------- .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 43 -- .../saturnclient/impl/mixins/TextMixin.java | 24 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ref/Matrix3x2fStackRef.java | 44 -- .../impl/ui/EntityDrawerImpl.java | 70 --- .../saturnclient/impl/ui/RenderScopeImpl.java | 345 ------------- .../impl/ui/SaturnScreenFabric.java | 134 ----- .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/event/KeyInputHandler.java | 54 --- .../mixin/DrawContextAccessor.java | 12 - .../saturnclient/mixin/NameTagMixin.java | 93 ---- .../mixin/PlayerEntityRendererMixin.java | 30 -- .../saturnclient/mixin/SetScreenMixin.java | 27 -- .../mixin/SplashOverlayMixin.java | 161 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.6/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 21 - .../src/main/resources/impl.mixins.json | 19 - .../main/resources/saturnclient.mixins.json | 17 - 60 files changed, 12 insertions(+), 3706 deletions(-) delete mode 100644 versions/1.21.6/build.gradle delete mode 100644 versions/1.21.6/settings.gradle delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.6/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.6/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.6/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.6/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index f40ffcf..d98683c 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.6) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.5) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index 1bdc62a..ce4dcac 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.7 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.6), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.6 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 and 1.21.5), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -55,7 +55,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.5,1.21.6 # only some versions +scripts/port.sh --to 1.21.4,1.21.5 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` @@ -78,6 +78,6 @@ The **Check** workflow runs the same compile on every pull request, so a version Add new versions to Stonecutter rather than copying a folder: 1. Create `versions//gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at ). Loom's version is shared, in the root `gradle.properties`. -2. Add `` to `stonecutterVersions` in `settings.gradle.kts`. +2. Add `` to `stonecutterVersions` in `settings.gradle.kts`. When moving an existing `mc-` version over instead, delete its `versions//src` and run `./gradlew ::clean` once: the new project shares the old one's `build/` folder, and classes compiled from the removed sources would otherwise end up in the jar. 3. Build it with `./gradlew ::compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew ::runClient`. 4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing. diff --git a/settings.gradle.kts b/settings.gradle.kts index 0df4901..106a746 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 613c813..70807b9 100644 --- a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -33,7 +33,10 @@ import net.minecraft.client.gui.render.state.TextGuiElementRenderState; import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; import net.minecraft.client.render.entity.state.EntityRenderState; +//? if >=1.21.7 { import net.minecraft.client.render.item.KeyedItemRenderState; +//?} else +//import net.minecraft.client.render.item.ItemRenderState; //? if >=1.21.11 import net.minecraft.client.texture.AbstractTexture; import net.minecraft.client.texture.Sprite; @@ -288,7 +291,10 @@ public class RenderScopeImpl implements RenderScope { private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, int z) { if (!stack.isEmpty()) { + //? if >=1.21.7 { KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); + //?} else + //ItemRenderState keyedItemRenderState = new ItemRenderState(); SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed); diff --git a/versions/1.21.6/build.gradle b/versions/1.21.6/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.6/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.6/gradle.properties b/versions/1.21.6/gradle.properties index f5e3bf0..9c060ae 100644 --- a/versions/1.21.6/gradle.properties +++ b/versions/1.21.6/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.6 yarn_mappings=1.21.6+build.1 loader_version=0.18.5 -loom_version=1.17.21 fabric_api_version=0.128.2+1.21.6 diff --git a/versions/1.21.6/settings.gradle b/versions/1.21.6/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.6/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index 2725e32..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, - PlayerEntityRenderState playerEntityRenderState, float f, float g) { - if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible - || playerEntityRenderState.skinTextures.capeTexture() != null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(ShaderUtils.getRenderLayer(customCape)); - - matrixStack.push(); - - matrixStack.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { - matrixStack.translate(0.0F, -0.053125F, 0.06875F); - } - - if (playerEntityRenderState.isInSneakingPose) { - matrixStack.translate(0, 0.16f, 0.0f); - matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, playerEntityRenderState.field_53537 / 108.0f); - float rawVelY = playerEntityRenderState.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, playerEntityRenderState.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - horizontalCurve = MathHelper.clamp(playerEntityRenderState.field_53537 / 150.0f, -1.0f, 1.0f); - - renderCape(matrixStack.peek(), vertexConsumer, playerEntityRenderState, light, OverlayTexture.DEFAULT_UV); - - matrixStack.pop(); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index cce3ec2..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - SaturnPlayer player = SaturnPlayer.get(state.name); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java deleted file mode 100644 index 8c1763d..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.saturnclient.impl.features.mixins.misc; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; - -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.render.LivingEntityRenderStateMixin; -import org.saturnclient.mod.mods.NametagsMod; -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; - -/** - * Intercepts nametag rendering and replaces the displayed text with - * the string produced by {@link NametagsMod#getNametagString}. - * - * Key changes from the original: - * - *
    - *
  • The old {@code NametagsFabric.EntityStateImpl} bridge class is - * replaced by {@link EntityFeatureImpl.RenderStateEntityState}, - * which wraps the {@link HealthRenderState} already injected into - * the render state by {@link LivingEntityRenderStateMixin}.
  • - *
  • The feature import changes from {@code Nametags} to - * {@link NametagsMod}; the two static methods - * ({@code shouldReplaceName} / {@code getNametagString}) are - * unchanged in signature.
  • - *
  • The entity's display name is extracted from the render state's - * {@code nameVisible} / text fields where available, falling back - * to the plain text string passed to this method.
  • - *
- * - * The re-entrancy guard ({@code saturn$rendering}) is kept intact to - * prevent infinite recursion when we call {@code renderLabelIfPresent} - * with the replacement text. - */ -@Mixin(EntityRenderer.class) -public abstract class NametagsMixin { - - /** Guards against the recursive call we make with the replacement text. */ - @Unique - private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); - - @Shadow - protected abstract void renderLabelIfPresent( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void saturn$replaceNametag( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - - // Skip our own recursive call - if (saturn$rendering.get()) - return; - - if (!NametagsMod.shouldReplaceName()) - return; - - // Only living entities carry health data - if (!(state instanceof LivingEntityRenderState living)) - return; - if (!(living instanceof HealthRenderState hrs)) - return; - - // Build the platform-neutral EntityState from the render-state snapshot - // (health/type were written by LivingEntityRendererMixin at extract time). - String customName = text != null ? text.getString() : null; - EntityFeatureImpl.RenderStateEntityState entityState = new EntityFeatureImpl.RenderStateEntityState( - customName, hrs); - - // Ask the feature for the replacement string - String replacement = NametagsMod.getNametagString(entityState); - if (replacement == null) - return; // feature decided not to replace this entity - - ci.cancel(); - saturn$rendering.set(true); - try { - renderLabelIfPresent(state, Text.literal(replacement), matrices, vertexConsumers, light); - } finally { - saturn$rendering.set(false); - } - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index bbb293b..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.misc.NametagsMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index b0a269a..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().getName(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().getId(); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index df9ad35..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return (SpriteRef) SaturnClient.client.getGuiAtlasManager().getSprite((InGameHud.getEffectTexture(getEffectType()))); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 3e1a8b8..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index c2bfe84..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index 17f78e9..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,345 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.ItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - ItemRenderState state = new ItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(state, stack, ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), state, x, y, scissorStack.peekLast())); - } catch (Throwable t) { - CrashReport report = CrashReport.create(t, "Rendering item"); - CrashReportSection section = report.addElement("Item being rendered"); - section.add("Item Type", () -> String.valueOf(stack.getItem())); - section.add("Item Components", () -> String.valueOf(stack.getComponents())); - section.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(report); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 3717c6f..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (screen.mouseClicked(mouseX, mouseY, button)) { - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { - return true; - } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (screen.mouseReleased(mouseX, mouseY, button)) { - return true; - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (screen.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index 7424639..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final String KEY_CATEGORY = "key.category.saturnclient"; - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - MAIN_MENU_KEY_ID, - InputUtil.Type.KEYSYM, - DEFAULT_MENU_KEY, - KEY_CATEGORY)); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java deleted file mode 100644 index 518494c..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec3d; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.saturnclient.SaturnClient; - -import java.util.UUID; - -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(value = EntityRenderer.class, priority = 1800) -public abstract class NameTagMixin { - @Shadow - public EntityRenderDispatcher dispatcher; - - /** - * @author HexLeo - * @reason Adds the Saturn Client icon to the player's name if they are online - * with Saturn Client - */ - @Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true) - private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - - UUID uuid = isSaturn(state); - - if (uuid != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid))); - - Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); - - renderLabel(state, iconText.append(nameText), matrices, - vertexConsumers, light); - - ci.cancel(); - } - } - - private UUID isSaturn(S state) { - if (state instanceof PlayerEntityRenderState) { - String name = ((PlayerEntityRenderState) state).name; - SaturnPlayer player = SaturnPlayer.get(name); - if (player != null) { - return player.uuid; - } - } - - return null; - } - - private void renderLabel(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light) { - Vec3d vec3d = state.nameLabelPos; - if (vec3d != null) { - boolean bl = !state.sneaking; - int i = "deadmau5".equals(text.getString()) ? -10 : 0; - matrices.push(); - matrices.translate(vec3d.x, vec3d.y + 0.5, vec3d.z); - matrices.multiply(this.dispatcher.getRotation()); - matrices.scale(0.025F, -0.025F, 0.025F); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - float f = (float) (-textRenderer.getWidth(text)) / 2.0F; - int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; - textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers, - bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light); - if (bl) { - textRenderer.draw(text, f, (float) i, -1, false, matrix4f, vertexConsumers, TextLayerType.NORMAL, 0, - light); - } - matrices.pop(); - } - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 0363dad..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index ecc4823..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 2a68cd6..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.getName(); - UUID uuid = profile.getId(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/resources/fabric.mod.json b/versions/1.21.6/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.6/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.6/src/main/resources/features.mixins.json b/versions/1.21.6/src/main/resources/features.mixins.json deleted file mode 100644 index 8d3c331..0000000 --- a/versions/1.21.6/src/main/resources/features.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "misc.NametagsMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.6/src/main/resources/impl.mixins.json b/versions/1.21.6/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.6/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.6/src/main/resources/saturnclient.mixins.json b/versions/1.21.6/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.6/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From c5665548a07ebcaa4704849576de6b5d5d61e6e1 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 06:23:23 +0200 Subject: [PATCH 08/10] Build 1.21.5 with Stonecutter from the shared src/ 1.21.5 is the first version before the 1.21.6 GUI rewrite, which moved GUI drawing from vertex consumers and a MatrixStack to render states and a 2D Matrix3x2fStack. - RenderScopeImpl and EntityDrawerImpl have two whole implementations, one per side of 1.21.6 (a single >=1.21.6 / else split), instead of conditionals scattered through them. Callers use RenderScopeImpl(context) in every version; 1.21.5's did the same thing through its (matrices, vertexConsumers) constructor. - MatrixStackMixin (MatrixStack as a MatrixStackRef) is real before 1.21.6 and empty from 1.21.6, registered everywhere like NametagsMixin. - DrawContextAccessor exposes the vertex consumers before 1.21.6 and the GUI render state from it. - Smaller changes: fog (BackgroundRenderer vs FogRenderer), the end portal texture arguments (ShaderUtils, now a flat three-way chain), the status effect sprite manager, and getIconId only from 1.21.6. Features 1.21.6+ lacks stay on 1.21.5, with a TODO: the title panorama behind Saturn screens and the background blur (screen.backgroundBlur, see #23). The 1.21.5 jar differs from the old one only in the helpers from earlier steps, the RenderScopeImpl(context) calls, the empty SaturnRenderState and unused Matrix3x2fStackRef, and 1.21.5's dead NameTagMixin (never registered) being gone. 1.21.6-1.21.11 only gain the empty MatrixStackMixin and its impl.mixins.json entry. Co-Authored-By: Claude Opus 5.5 --- settings.gradle.kts | 2 +- .../impl/cosmetics/utils/ShaderUtils.java | 9 +- .../render/BackgroundRendererMixin.java | 6 + .../impl/mixins/MatrixStackMixin.java | 22 +- .../impl/mixins/StatusEffectMixin.java | 7 +- .../impl/ui/EntityDrawerImpl.java | 88 ++++ .../saturnclient/impl/ui/RenderScopeImpl.java | 417 +++++++++++++++- .../impl/ui/SaturnScreenFabric.java | 29 +- .../mixin/DrawContextAccessor.java | 8 + src/main/resources/impl.mixins.json | 1 + versions/1.21.5/build.gradle | 101 ---- versions/1.21.5/gradle.properties | 1 - versions/1.21.5/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 459 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 42 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 71 --- .../impl/cosmetics/utils/ShaderUtils.java | 39 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../features/mixins/misc/NametagsMixin.java | 95 ---- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 37 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 60 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 85 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 254 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MinecraftClientMixin.java | 162 ------- .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 44 -- .../saturnclient/impl/mixins/TextMixin.java | 24 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ui/EntityDrawerImpl.java | 85 ---- .../saturnclient/impl/ui/RenderScopeImpl.java | 412 ---------------- .../impl/ui/SaturnScreenFabric.java | 154 ------ .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/event/KeyInputHandler.java | 54 --- .../mixin/DrawContextAccessor.java | 12 - .../saturnclient/mixin/NameTagMixin.java | 93 ---- .../mixin/PlayerEntityRendererMixin.java | 30 -- .../saturnclient/mixin/SetScreenMixin.java | 27 -- .../mixin/SplashOverlayMixin.java | 161 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.5/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 21 - .../src/main/resources/impl.mixins.json | 20 - .../main/resources/saturnclient.mixins.json | 17 - 65 files changed, 578 insertions(+), 3774 deletions(-) rename {versions/1.21.5/src => src}/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java (73%) delete mode 100644 versions/1.21.5/build.gradle delete mode 100644 versions/1.21.5/settings.gradle delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.5/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.5/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.5/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.5/src/main/resources/saturnclient.mixins.json diff --git a/settings.gradle.kts b/settings.gradle.kts index 106a746..b32f1a3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java index 4935949..0038258 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java @@ -31,13 +31,20 @@ public class ShaderUtils { RenderSetup.builder(END_GATEWAY_PIPELINE) .texture("Sampler0", AbstractEndPortalBlockEntityRenderer.SKY_TEXTURE) .texture("Sampler1", AbstractEndPortalBlockEntityRenderer.PORTAL_TEXTURE).build()); - //?} else { + //?} else if >=1.21.6 { /*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, END_GATEWAY_PIPELINE, RenderLayer.MultiPhaseParameters.builder() .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) .build(false)); + *///?} else { + /*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, + END_GATEWAY_PIPELINE, + RenderLayer.MultiPhaseParameters.builder() + .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false) + .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false).build()) + .build(false)); *///?} public static RenderLayer getRenderLayer(IdentifierRef texture) { diff --git a/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java index 0a61479..3d3602e 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java @@ -1,13 +1,19 @@ package org.saturnclient.impl.features.mixins.render; +//? if >=1.21.6 { import net.minecraft.client.render.fog.FogRenderer; +//?} else +//import net.minecraft.client.render.BackgroundRenderer; import org.saturnclient.mod.mods.NoFogMod; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; +//? if >=1.21.6 { @Mixin(FogRenderer.class) +//?} else +//@Mixin(BackgroundRenderer.class) public class BackgroundRendererMixin { // fog @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java similarity index 73% rename from versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java rename to src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java index 4c4ae39..dd47753 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java @@ -1,14 +1,22 @@ package org.saturnclient.impl.mixins; -import org.joml.Quaternionfc; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import net.minecraft.client.util.math.MatrixStack; +import org.spongepowered.asm.mixin.Mixin; +//? if <1.21.6 { +/*import org.joml.Quaternionfc; +import org.saturnclient.common.ref.render.MatrixStackRef; +import org.spongepowered.asm.mixin.Shadow; import net.minecraft.util.math.RotationAxis; +*///?} +/** + * Makes MatrixStack a MatrixStackRef, for GUI drawing before 1.21.6. From 1.21.6 the GUI uses a 2D + * Matrix3x2fStack (Matrix3x2fStackRef) instead, so this mixin is empty but stays registered, keeping + * impl.mixins.json the same for every version. + */ @Mixin(MatrixStack.class) -public abstract class MatrixStackMixin implements MatrixStackRef { +//? if <1.21.6 { +/*public abstract class MatrixStackMixin implements MatrixStackRef { @Shadow public abstract void push(); @@ -46,4 +54,6 @@ public abstract class MatrixStackMixin implements MatrixStackRef { public void rotate(float angle) { multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle)); } -} \ No newline at end of file +} +*///?} else +public abstract class MatrixStackMixin {} diff --git a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java index 4977a40..556d33a 100644 --- a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java @@ -34,16 +34,21 @@ public abstract class StatusEffectMixin implements EffectRef { // 1.21.9 changed the GUI atlas, so newer versions draw the effect's texture (getIconId) instead. //? if >=1.21.9 { return null; - //?} else + //?} else if >=1.21.6 { //return (SpriteRef) SaturnClient.client.getGuiAtlasManager().getSprite((InGameHud.getEffectTexture(getEffectType()))); + //?} else + //return (SpriteRef) SaturnClient.client.getStatusEffectSpriteManager().getSprite(getEffectType()); } + // Before 1.21.6 there's no InGameHud.getEffectTexture; getIcon's sprite is used there instead. + //? if >=1.21.6 { @Override public IdentifierRef getIconId() { Identifier id = InGameHud.getEffectTexture(getEffectType()); return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png"); } + //?} @Override public String getInfiniteText() { diff --git a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index 31761ce..ebbe007 100644 --- a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -1,5 +1,8 @@ package org.saturnclient.impl.ui; +// Entities in the UI are drawn through the GUI render state from 1.21.6, and straight into vertex +// consumers before. This file has one implementation for each side. +//? if >=1.21.6 { import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; @@ -75,3 +78,88 @@ public class EntityDrawerImpl implements EntityDrawer { i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); } } +//?} else { +/*import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.ui.ElementContext; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.components.SkinPreview.EntityDrawer; + +import net.minecraft.client.render.DiffuseLighting; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.entity.LivingEntity; + +public class EntityDrawerImpl implements EntityDrawer { + public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, + float mouseX, + float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { + float g = (float) (x1 + x2) / 2.0F; + float h = (float) (y1 + y2) / 2.0F; + renderScope.enableScissor(0, 6, x2, y2); + float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); + float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); + Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); + float k = entity.bodyYaw; + float l = entity.getYaw(); + float m = entity.getPitch(); + float n = entity.lastHeadYaw; + float o = entity.headYaw; + entity.setYaw(angle); + entity.bodyYaw = angle; + entity.setPitch(-(j * 20.0F)); + entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); + entity.lastHeadYaw = entity.getHeadYaw(); + entity.setCustomNameVisible(false); + + float p = entity.getScale(); + Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); + float q = (float) size / p; + drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity); + + entity.setCustomNameVisible(true); + entity.bodyYaw = k; + entity.setYaw(l); + entity.setPitch(m); + entity.lastHeadYaw = n; + entity.headYaw = o; + renderScope.disableScissor(); + } + + public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, + Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { + if (renderScope instanceof RenderScopeImpl scopeImpl) { + scopeImpl.matrices.push(); + scopeImpl.matrices.translate((double) x, (double) y, 0); + scopeImpl.matrices.scale(size, size, -size); + scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); + scopeImpl.matrices.multiply(quaternionf); + scopeImpl.draw(); + DiffuseLighting.disableGuiDepthLighting(); + EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + + entityRenderDispatcher.setRenderShadows(false); + scopeImpl.draw((vertexConsumers) -> { + entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, + scopeImpl.matrices, vertexConsumers, 15728880); + }); + + scopeImpl.draw(); + entityRenderDispatcher.setRenderShadows(true); + scopeImpl.getMatrixStack().pop(); + DiffuseLighting.enableGuiDepthLighting(); + } + + } + + @Override + public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { + LivingEntity entity = SaturnClient.client.player; + if (entity != null) { + drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, + negativeAngle); + } + } +} +*///?} diff --git a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 70807b9..fbba7b2 100644 --- a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -1,5 +1,8 @@ package org.saturnclient.impl.ui; +// 1.21.6 rewrote GUI rendering: render states and a 2D matrix stack (Matrix3x2fStack) instead of +// drawing into vertex consumers with a MatrixStack. This file has one implementation for each side. +//? if >=1.21.6 { import java.util.ArrayDeque; import java.util.Deque; import java.util.Objects; @@ -361,4 +364,416 @@ public class RenderScopeImpl implements RenderScope { overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, this.scissorStack.peekLast())); } -} \ No newline at end of file +} +//?} else { +/*import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Objects; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix4f; + +import com.mojang.blaze3d.systems.RenderSystem; + +import org.saturnclient.common.ref.asset.IdentifierRef; +import org.saturnclient.common.ref.asset.SpriteRef; +import org.saturnclient.common.ref.game.ItemStackRef; +import org.saturnclient.common.ref.render.MatrixStackRef; +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.mixin.DrawContextAccessor; +import org.saturnclient.ui.RenderScope; +import org.saturnclient.ui.resources.Fonts; +import org.saturnclient.ui.resources.SvgTexture; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.font.TextRenderer.TextLayerType; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.ScreenRect; +import net.minecraft.client.render.DiffuseLighting; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.item.ItemRenderState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.Window; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemDisplayContext; +import net.minecraft.item.ItemStack; + +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.crash.CrashException; +import net.minecraft.util.crash.CrashReport; +import net.minecraft.util.crash.CrashReportSection; +import net.minecraft.world.World; + +public class RenderScopeImpl implements RenderScope { + // ---------------------------- + // Fields + // ---------------------------- + public MatrixStack matrices; + public VertexConsumerProvider.Immediate vertexConsumers; + private ScissorStack scissorStack = new ScissorStack(); + private int opacity = 255 << 24; + private final ItemRenderState itemRenderState; + + // ---------------------------- + // Constructors + // ---------------------------- + public RenderScopeImpl(DrawContext context) { + this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); + } + + public RenderScopeImpl(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) { + this.matrices = matrices; + this.vertexConsumers = vertexConsumers; + this.scissorStack = new ScissorStack(); + this.itemRenderState = new ItemRenderState(); + } + + // ---------------------------- + // Matrix & Transform + // ---------------------------- + @Override + public MatrixStackRef getMatrixStack() { + return (MatrixStackRef) matrices; + } + + // ---------------------------- + // Color & Opacity + // ---------------------------- + @Override + public void setOpacity(float alpha) { + this.opacity = (int) (alpha * 255) << 24; + } + + @Override + public int getColor(int color) { + int originalAlpha = (color >>> 24) & 0xFF; + int newAlpha = (opacity >>> 24) & 0xFF; + int mixedAlpha = (originalAlpha * newAlpha) / 255; + return (mixedAlpha << 24) | (color & 0x00FFFFFF); + } + + // ---------------------------- + // Draw / Window Info + // ---------------------------- + @Override + public void draw() { + this.vertexConsumers.draw(); + } + + @Override + public int getScaledWindowWidth() { + return SaturnClient.client.getWindow().getScaledWidth(); + } + + @Override + public int getScaledWindowHeight() { + return SaturnClient.client.getWindow().getScaledHeight(); + } + + public void draw(Consumer drawer) { + drawer.accept(this.vertexConsumers); + this.vertexConsumers.draw(); + } + + // ---------------------------- + // Shapes + // ---------------------------- + @Override + public void drawRectangle(int x, int y, int width, int height, int color) { + if (color == 0) + return; + color = getColor(color); + + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); + vertexConsumer.vertex(matrix4f, x1, y1, 0).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).color(color); + } + + @Override + public void fill(int x1, int y1, int x2, int y2, int color) { + fill(x1, y1, x2, y2, 0, color); + } + + public void fill(int x1, int y1, int x2, int y2, int z, int color) { + fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { + fill(layer, x1, y1, x2, y2, 0, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); + vertexConsumer.vertex(matrix4f, x1, y1, z).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, z).color(color); + } + + @Override + public void drawBorder(int x, int y, int width, int height, int color) { + fill(x, y, x + width, y + 1, color); + fill(x, y + height - 1, x + width, y + height, color); + fill(x, y + 1, x + 1, y + height - 1, color); + fill(x + width - 1, y + 1, x + width, y + height - 1, color); + } + + // ---------------------------- + // Text + // ---------------------------- + @Override + public void drawText(String text, int x, int y, int font, int color) { + drawText(1.0f, text, x, y, font, color); + } + + @Override + public void drawText(float scale, String text, int x, int y, int font, int color) { + if (color == 0) + return; + if (font == 0) + scale *= 2; + + int i = 0; + for (String line : text.split("\n")) { + color = getColor(color); + matrices.push(); + matrices.translate(x, y + i * Fonts.getHeight(), 0); + matrices.scale(scale, scale, 1.0f); + TextRenderer textRenderer = SaturnClient.client.textRenderer; + textRenderer.draw((Text) Fonts.setFont(line, font), 0, font == 0 ? 1 : 7, color, false, + matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, 15728880); + matrices.pop(); + i++; + } + } + + // ---------------------------- + // Textures & Sprites + // ---------------------------- + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight) { + drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { + drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, + (u + 0.0f) / textureWidth, (u + regionWidth) / textureWidth, + (v + 0.0f) / textureHeight, (v + regionHeight) / textureHeight, color); + } + + @Override + public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { + drawSpriteStretched(sprite, x, y, width, height, -1); + } + + @Override + public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { + Sprite sprite = (Sprite) saturnSprite; + if (color == 0) + return; + if (width != 0 && height != 0) { + drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, + sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color); + } + } + + private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, + float u1, float u2, float v1, float v2, int color) { + if (sprite.toString().endsWith(".svg")) { + sprite = (Identifier) (Object) SvgTexture.getSvg((IdentifierRef) (Object) sprite, (x2 - x1) * 2, + (y2 - y1) * 2); + } + if (color == 0) + return; + + x1 *= 4; + x2 *= 4; + y1 *= 4; + y2 *= 4; + color = getColor(color); + + matrices.push(); + matrices.scale(0.25f, 0.25f, 1.0f); + RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); + Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); + vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(u1, v1).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(u1, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(u2, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(u2, v1).color(color); + matrices.pop(); + } + + // ---------------------------- + // Items + // ---------------------------- + @Override + public void drawItem(ItemStackRef item, int x, int y) { + drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, + int seed) { + drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, + int z) { + if (stack.isEmpty()) + return; + + SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, + seed); + + if (!stack.isEmpty()) { + SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, + ItemDisplayContext.GUI, world, + entity, seed); + this.matrices.push(); + this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z)); + + try { + this.matrices.scale(16.0F, -16.0F, 16.0F); + boolean bl = !this.itemRenderState.isSideLit(); + if (bl) { + this.draw(); + DiffuseLighting.disableGuiDepthLighting(); + } + + this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); + this.draw(); + if (bl) { + DiffuseLighting.enableGuiDepthLighting(); + } + } catch (Throwable throwable) { + CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); + CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); + crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); + crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); + crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); + throw new CrashException(crashReport); + } + + this.matrices.pop(); + } + } + + // ---------------------------- + // Scissor / Clipping + // ---------------------------- + @Override + public void enableScissor(int x1, int y1, int x2, int y2) { + ScreenRect screenRect = new ScreenRect(x1, y1, x2 - x1, y2 - y1) + .transform(matrices.peek().getPositionMatrix()); + setScissor(scissorStack.push(screenRect)); + } + + @Override + public void disableScissor() { + setScissor(scissorStack.pop()); + } + + @Override + public boolean scissorContains(int x, int y) { + return scissorStack.containsPoint(x, y); + } + + private void setScissor(@Nullable ScreenRect rect) { + draw(); + if (rect != null) { + Window window = SaturnClient.client.getWindow(); + int framebufferHeight = window.getFramebufferHeight(); + double scaleFactor = window.getScaleFactor(); + RenderSystem.enableScissor( + (int) (rect.getLeft() * scaleFactor), + (int) (framebufferHeight - rect.getBottom() * scaleFactor), + Math.max(0, (int) (rect.width() * scaleFactor)), + Math.max(0, (int) (rect.height() * scaleFactor))); + } else { + RenderSystem.disableScissor(); + } + } + + static class ScissorStack { + private final Deque stack = new ArrayDeque<>(); + + public ScreenRect push(ScreenRect p_281812_) { + ScreenRect screenrectangle = this.stack.peekLast(); + if (screenrectangle != null) { + ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), + ScreenRect.empty()); + this.stack.addLast(screenrectangle1); + return screenrectangle1; + } else { + this.stack.addLast(p_281812_); + return p_281812_; + } + } + + @Nullable + public ScreenRect pop() { + if (this.stack.isEmpty()) { + throw new IllegalStateException("Scissor stack underflow"); + } else { + this.stack.removeLast(); + return this.stack.peekLast(); + } + } + + public boolean containsPoint(int p_329411_, int p_333404_) { + return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); + } + } +} +*///?} diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index 38c3619..63fe7d5 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -16,6 +16,11 @@ import net.minecraft.client.gui.RotatingCubeMapRenderer; import net.minecraft.client.gui.screen.Screen; //? if >=1.21.9 import net.minecraft.client.input.KeyInput; +//? if <1.21.6 { +/*import net.minecraft.client.gl.PostEffectProcessor; +import net.minecraft.client.render.DefaultFramebufferSet; +import net.minecraft.client.util.Pool; +*///?} import net.minecraft.client.texture.ResourceTexture; import net.minecraft.client.texture.TextureManager; import net.minecraft.text.Text; @@ -32,6 +37,8 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); } + //? if <1.21.6 + //private final Pool pool = new Pool(3); public final SaturnScreen screen; public static void preload(MinecraftClient client) { @@ -55,6 +62,8 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { screen.init(); } + //? if <1.21.6 + //@SuppressWarnings("deprecation") @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (screen.start == null) { @@ -65,10 +74,28 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { mouseX *= 2; mouseY *= 2; + // TODO: the panorama and the background blur (screen.backgroundBlur) are only drawn before + // 1.21.6 so far. See also issue #23. if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); + //? if <1.21.6 + //ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, screen.backgroundOpacity, delta); } + //? if <1.21.6 { + /*PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( + Identifier.ofVanilla("blur"), + DefaultFramebufferSet.MAIN_ONLY); + + if (postEffectProcessor != null) { + float radius = screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f); + postEffectProcessor.render( + this.client.getFramebuffer(), + this.pool, + pass -> pass.setUniform("Radius", radius) + ); + } + *///?} + RenderScope renderScope = new RenderScopeImpl(context); screen.render(renderScope, mouseX, mouseY, delta, elapsed); diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java index 9c2d8f0..d9f4349 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java @@ -1,12 +1,20 @@ package org.saturnclient.saturnclient.mixin; import net.minecraft.client.gui.DrawContext; +//? if >=1.21.6 { import net.minecraft.client.gui.render.state.GuiRenderState; +//?} else +//import net.minecraft.client.render.VertexConsumerProvider; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(DrawContext.class) public interface DrawContextAccessor { + //? if >=1.21.6 { @Accessor("state") GuiRenderState getState(); + //?} else { + /*@Accessor("vertexConsumers") + VertexConsumerProvider.Immediate getVertexConsumers(); + *///?} } diff --git a/src/main/resources/impl.mixins.json b/src/main/resources/impl.mixins.json index ef9d58f..094792b 100644 --- a/src/main/resources/impl.mixins.json +++ b/src/main/resources/impl.mixins.json @@ -6,6 +6,7 @@ "client": [ "IdentifierMixin", "ItemStackMixin", + "MatrixStackMixin", "MinecraftClientMixin", "QuaternionfMixin", "WindowMixin", diff --git a/versions/1.21.5/build.gradle b/versions/1.21.5/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.5/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.5/gradle.properties b/versions/1.21.5/gradle.properties index b71b756..6c193be 100644 --- a/versions/1.21.5/gradle.properties +++ b/versions/1.21.5/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.5 yarn_mappings=1.21.5+build.1 loader_version=0.18.4 -loom_version=1.17.21 fabric_api_version=0.128.2+1.21.5 diff --git a/versions/1.21.5/settings.gradle b/versions/1.21.5/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.5/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index 2725e32..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, - PlayerEntityRenderState playerEntityRenderState, float f, float g) { - if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible - || playerEntityRenderState.skinTextures.capeTexture() != null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(ShaderUtils.getRenderLayer(customCape)); - - matrixStack.push(); - - matrixStack.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { - matrixStack.translate(0.0F, -0.053125F, 0.06875F); - } - - if (playerEntityRenderState.isInSneakingPose) { - matrixStack.translate(0, 0.16f, 0.0f); - matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, playerEntityRenderState.field_53537 / 108.0f); - float rawVelY = playerEntityRenderState.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, playerEntityRenderState.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - horizontalCurve = MathHelper.clamp(playerEntityRenderState.field_53537 / 150.0f, -1.0f, 1.0f); - - renderCape(matrixStack.peek(), vertexConsumer, playerEntityRenderState, light, OverlayTexture.DEFAULT_UV); - - matrixStack.pop(); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index cce3ec2..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - SaturnPlayer player = SaturnPlayer.get(state.name); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 9adf50d..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java deleted file mode 100644 index 8c1763d..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.saturnclient.impl.features.mixins.misc; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; - -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.render.LivingEntityRenderStateMixin; -import org.saturnclient.mod.mods.NametagsMod; -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; - -/** - * Intercepts nametag rendering and replaces the displayed text with - * the string produced by {@link NametagsMod#getNametagString}. - * - * Key changes from the original: - * - *
    - *
  • The old {@code NametagsFabric.EntityStateImpl} bridge class is - * replaced by {@link EntityFeatureImpl.RenderStateEntityState}, - * which wraps the {@link HealthRenderState} already injected into - * the render state by {@link LivingEntityRenderStateMixin}.
  • - *
  • The feature import changes from {@code Nametags} to - * {@link NametagsMod}; the two static methods - * ({@code shouldReplaceName} / {@code getNametagString}) are - * unchanged in signature.
  • - *
  • The entity's display name is extracted from the render state's - * {@code nameVisible} / text fields where available, falling back - * to the plain text string passed to this method.
  • - *
- * - * The re-entrancy guard ({@code saturn$rendering}) is kept intact to - * prevent infinite recursion when we call {@code renderLabelIfPresent} - * with the replacement text. - */ -@Mixin(EntityRenderer.class) -public abstract class NametagsMixin { - - /** Guards against the recursive call we make with the replacement text. */ - @Unique - private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); - - @Shadow - protected abstract void renderLabelIfPresent( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void saturn$replaceNametag( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - - // Skip our own recursive call - if (saturn$rendering.get()) - return; - - if (!NametagsMod.shouldReplaceName()) - return; - - // Only living entities carry health data - if (!(state instanceof LivingEntityRenderState living)) - return; - if (!(living instanceof HealthRenderState hrs)) - return; - - // Build the platform-neutral EntityState from the render-state snapshot - // (health/type were written by LivingEntityRendererMixin at extract time). - String customName = text != null ? text.getString() : null; - EntityFeatureImpl.RenderStateEntityState entityState = new EntityFeatureImpl.RenderStateEntityState( - customName, hrs); - - // Ask the feature for the replacement string - String replacement = NametagsMod.getNametagString(entityState); - if (replacement == null) - return; // feature decided not to replace this entity - - ci.cancel(); - saturn$rendering.set(true); - try { - renderLabelIfPresent(state, Text.literal(replacement), matrices, vertexConsumers, light); - } finally { - saturn$rendering.set(false); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index a9f641a..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.BackgroundRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(BackgroundRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index bbb293b..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.misc.NametagsMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f4efb30..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl( - context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index b0a269a..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().getName(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().getId(); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index a164eae..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return (SpriteRef) SaturnClient.client - .getStatusEffectSpriteManager() - .getSprite(getEffectType()); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 3e1a8b8..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index 7f0674b..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, - float mouseX, - float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { - float g = (float) (x1 + x2) / 2.0F; - float h = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(0, 6, x2, y2); - float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); - float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); - float k = entity.bodyYaw; - float l = entity.getYaw(); - float m = entity.getPitch(); - float n = entity.lastHeadYaw; - float o = entity.headYaw; - entity.setYaw(angle); - entity.bodyYaw = angle; - entity.setPitch(-(j * 20.0F)); - entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); - entity.lastHeadYaw = entity.getHeadYaw(); - entity.setCustomNameVisible(false); - - float p = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); - float q = (float) size / p; - drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity); - - entity.setCustomNameVisible(true); - entity.bodyYaw = k; - entity.setYaw(l); - entity.setPitch(m); - entity.lastHeadYaw = n; - entity.headYaw = o; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, - Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - if (renderScope instanceof RenderScopeImpl scopeImpl) { - scopeImpl.matrices.push(); - scopeImpl.matrices.translate((double) x, (double) y, 0); - scopeImpl.matrices.scale(size, size, -size); - scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); - scopeImpl.matrices.multiply(quaternionf); - scopeImpl.draw(); - DiffuseLighting.disableGuiDepthLighting(); - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - - entityRenderDispatcher.setRenderShadows(false); - scopeImpl.draw((vertexConsumers) -> { - entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - scopeImpl.matrices, vertexConsumers, 15728880); - }); - - scopeImpl.draw(); - entityRenderDispatcher.setRenderShadows(true); - scopeImpl.getMatrixStack().pop(); - DiffuseLighting.enableGuiDepthLighting(); - } - - } - - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, - negativeAngle); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b4688d8..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,412 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; -import java.util.function.Consumer; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; - -import com.mojang.blaze3d.systems.RenderSystem; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.ItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.util.Window; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - // ---------------------------- - // Fields - // ---------------------------- - public MatrixStack matrices; - public VertexConsumerProvider.Immediate vertexConsumers; - private ScissorStack scissorStack = new ScissorStack(); - private int opacity = 255 << 24; - private final ItemRenderState itemRenderState; - - // ---------------------------- - // Constructors - // ---------------------------- - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); - } - - public RenderScopeImpl(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) { - this.matrices = matrices; - this.vertexConsumers = vertexConsumers; - this.scissorStack = new ScissorStack(); - this.itemRenderState = new ItemRenderState(); - } - - // ---------------------------- - // Matrix & Transform - // ---------------------------- - @Override - public MatrixStackRef getMatrixStack() { - return (MatrixStackRef) matrices; - } - - // ---------------------------- - // Color & Opacity - // ---------------------------- - @Override - public void setOpacity(float alpha) { - this.opacity = (int) (alpha * 255) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - // ---------------------------- - // Draw / Window Info - // ---------------------------- - @Override - public void draw() { - this.vertexConsumers.draw(); - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - public void draw(Consumer drawer) { - drawer.accept(this.vertexConsumers); - this.vertexConsumers.draw(); - } - - // ---------------------------- - // Shapes - // ---------------------------- - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x1 < x2) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y1 < y2) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); - vertexConsumer.vertex(matrix4f, x1, y1, 0).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, 0).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, 0).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, 0).color(color); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - fill(x1, y1, x2, y2, 0, color); - } - - public void fill(int x1, int y1, int x2, int y2, int z, int color) { - fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { - fill(layer, x1, y1, x2, y2, 0, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - if (x1 < x2) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y1 < y2) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); - vertexConsumer.vertex(matrix4f, x1, y1, z).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, z).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, z).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, z).color(color); - } - - @Override - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - // ---------------------------- - // Text - // ---------------------------- - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int i = 0; - for (String line : text.split("\n")) { - color = getColor(color); - matrices.push(); - matrices.translate(x, y + i * Fonts.getHeight(), 0); - matrices.scale(scale, scale, 1.0f); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - textRenderer.draw((Text) Fonts.setFont(line, font), 0, font == 0 ? 1 : 7, color, false, - matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, 15728880); - matrices.pop(); - i++; - } - } - - // ---------------------------- - // Textures & Sprites - // ---------------------------- - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0.0f) / textureWidth, (u + regionWidth) / textureWidth, - (v + 0.0f) / textureHeight, (v + regionHeight) / textureHeight, color); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { - Sprite sprite = (Sprite) saturnSprite; - if (color == 0) - return; - if (width != 0 && height != 0) { - drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, - sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color); - } - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg((IdentifierRef) (Object) sprite, (x2 - x1) * 2, - (y2 - y1) * 2); - } - if (color == 0) - return; - - x1 *= 4; - x2 *= 4; - y1 *= 4; - y2 *= 4; - color = getColor(color); - - matrices.push(); - matrices.scale(0.25f, 0.25f, 1.0f); - RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); - vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(u1, v1).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(u1, v2).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(u2, v2).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(u2, v1).color(color); - matrices.pop(); - } - - // ---------------------------- - // Items - // ---------------------------- - @Override - public void drawItem(ItemStackRef item, int x, int y) { - drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (stack.isEmpty()) - return; - - SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, - seed); - - if (!stack.isEmpty()) { - SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - this.matrices.push(); - this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z)); - - try { - this.matrices.scale(16.0F, -16.0F, 16.0F); - boolean bl = !this.itemRenderState.isSideLit(); - if (bl) { - this.draw(); - DiffuseLighting.disableGuiDepthLighting(); - } - - this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); - this.draw(); - if (bl) { - DiffuseLighting.enableGuiDepthLighting(); - } - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - - this.matrices.pop(); - } - } - - // ---------------------------- - // Scissor / Clipping - // ---------------------------- - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect screenRect = new ScreenRect(x1, y1, x2 - x1, y2 - y1) - .transform(matrices.peek().getPositionMatrix()); - setScissor(scissorStack.push(screenRect)); - } - - @Override - public void disableScissor() { - setScissor(scissorStack.pop()); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.containsPoint(x, y); - } - - private void setScissor(@Nullable ScreenRect rect) { - draw(); - if (rect != null) { - Window window = SaturnClient.client.getWindow(); - int framebufferHeight = window.getFramebufferHeight(); - double scaleFactor = window.getScaleFactor(); - RenderSystem.enableScissor( - (int) (rect.getLeft() * scaleFactor), - (int) (framebufferHeight - rect.getBottom() * scaleFactor), - Math.max(0, (int) (rect.width() * scaleFactor)), - Math.max(0, (int) (rect.height() * scaleFactor))); - } else { - RenderSystem.disableScissor(); - } - } - - static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect p_281812_) { - ScreenRect screenrectangle = this.stack.peekLast(); - if (screenrectangle != null) { - ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), - ScreenRect.empty()); - this.stack.addLast(screenrectangle1); - return screenrectangle1; - } else { - this.stack.addLast(p_281812_); - return p_281812_; - } - } - - @Nullable - public ScreenRect pop() { - if (this.stack.isEmpty()) { - throw new IllegalStateException("Scissor stack underflow"); - } else { - this.stack.removeLast(); - return this.stack.peekLast(); - } - } - - public boolean containsPoint(int p_329411_, int p_333404_) { - return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 05bcd6e..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.render.DefaultFramebufferSet; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.client.util.Pool; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - private final Pool pool = new Pool(3); - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @SuppressWarnings("deprecation") - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, screen.backgroundOpacity, delta); - } - - PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( - Identifier.ofVanilla("blur"), - DefaultFramebufferSet.MAIN_ONLY); - - if (postEffectProcessor != null) { - float radius = screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f); - postEffectProcessor.render( - this.client.getFramebuffer(), - this.pool, - pass -> pass.setUniform("Radius", radius) - ); - } - - RenderScope renderScope = new RenderScopeImpl(context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (screen.mouseClicked(mouseX, mouseY, button)) { - return true; - } - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { - return true; - } - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (screen.mouseReleased(mouseX, mouseY, button)) { - return true; - } - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (screen.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index 4e037c7..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final String KEY_CATEGORY = "key.category.saturnclient"; - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - MAIN_MENU_KEY_ID, - InputUtil.Type.KEYSYM, - DEFAULT_MENU_KEY, - KEY_CATEGORY)); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index f049e40..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.VertexConsumerProvider; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("vertexConsumers") - VertexConsumerProvider.Immediate getVertexConsumers(); -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java deleted file mode 100644 index 518494c..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec3d; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.saturnclient.SaturnClient; - -import java.util.UUID; - -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(value = EntityRenderer.class, priority = 1800) -public abstract class NameTagMixin { - @Shadow - public EntityRenderDispatcher dispatcher; - - /** - * @author HexLeo - * @reason Adds the Saturn Client icon to the player's name if they are online - * with Saturn Client - */ - @Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true) - private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - - UUID uuid = isSaturn(state); - - if (uuid != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid))); - - Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); - - renderLabel(state, iconText.append(nameText), matrices, - vertexConsumers, light); - - ci.cancel(); - } - } - - private UUID isSaturn(S state) { - if (state instanceof PlayerEntityRenderState) { - String name = ((PlayerEntityRenderState) state).name; - SaturnPlayer player = SaturnPlayer.get(name); - if (player != null) { - return player.uuid; - } - } - - return null; - } - - private void renderLabel(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light) { - Vec3d vec3d = state.nameLabelPos; - if (vec3d != null) { - boolean bl = !state.sneaking; - int i = "deadmau5".equals(text.getString()) ? -10 : 0; - matrices.push(); - matrices.translate(vec3d.x, vec3d.y + 0.5, vec3d.z); - matrices.multiply(this.dispatcher.getRotation()); - matrices.scale(0.025F, -0.025F, 0.025F); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - float f = (float) (-textRenderer.getWidth(text)) / 2.0F; - int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; - textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers, - bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light); - if (bl) { - textRenderer.draw(text, f, (float) i, -1, false, matrix4f, vertexConsumers, TextLayerType.NORMAL, 0, - light); - } - matrices.pop(); - } - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 0363dad..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index ecc4823..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 2a68cd6..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.getName(); - UUID uuid = profile.getId(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.5/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.5/src/main/resources/fabric.mod.json b/versions/1.21.5/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.5/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.5/src/main/resources/features.mixins.json b/versions/1.21.5/src/main/resources/features.mixins.json deleted file mode 100644 index 8d3c331..0000000 --- a/versions/1.21.5/src/main/resources/features.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "misc.NametagsMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.5/src/main/resources/impl.mixins.json b/versions/1.21.5/src/main/resources/impl.mixins.json deleted file mode 100644 index 094792b..0000000 --- a/versions/1.21.5/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MatrixStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.5/src/main/resources/saturnclient.mixins.json b/versions/1.21.5/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.5/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From 25a19d7951e7c05c4c5123cb77cc186ec335115d Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 06:34:32 +0200 Subject: [PATCH 09/10] Build 1.21.4 with Stonecutter; every version now shares src/ Step 6 of #8. versions/1.21.4/src is gone, so all eight versions (1.21.4 to 1.21.11) build from src/. 1.21.4's differences from 1.21.5 are behind version comments: - The end gateway render layer has no render pipeline before 1.21.5 (ShaderUtils: the pipeline field only exists from 1.21.5, and the layer is a four-way chain). - Hat head rotation, the NativeImageBackedTexture constructor, armor slots (inventory.armor vs getEquippedStack), MatrixStackMixin's Quaternionf, and inside the pre-1.21.6 implementations: prevHeadYaw, GUI lighting, ModelTransformationMode, item depth, setShaderTexture and the blur uniform call. Those are one-line version comments, since the pre-1.21.6 blocks are already inside /* */ on newer versions. 1.21.5's drawItem wrapped its body in a second isEmpty check after already returning early for empty stacks; the redundant check is gone, so 1.21.4 and 1.21.5 share the body. Freelook's zoom-out (FreelookMod.shouldZoomOut in GameRendererMixin) only existed on 1.21.4. It doesn't depend on the Minecraft version, so it's back on every version. With no old copies left, the mc- fallback in settings.gradle.kts and scripts/port.sh are removed, and README and VERSION_GUIDE describe the single layout. Co-Authored-By: Claude Opus 5.5 --- README.MD | 4 +- VERSION_GUIDE.md | 35 +- gradle.properties | 2 +- scripts/port.sh | 184 ------- settings.gradle.kts | 14 +- .../impl/cosmetics/HatFeatureRenderer.java | 3 + .../impl/cosmetics/utils/IdentifierUtils.java | 3 + .../impl/cosmetics/utils/ShaderUtils.java | 28 +- .../mixins/render/GameRendererMixin.java | 4 + .../features/player/PlayerFeatureImpl.java | 12 + .../impl/mixins/MatrixStackMixin.java | 13 +- .../impl/ui/EntityDrawerImpl.java | 12 + .../saturnclient/impl/ui/RenderScopeImpl.java | 63 +-- .../impl/ui/SaturnScreenFabric.java | 11 +- versions/1.21.4/build.gradle | 101 ---- versions/1.21.4/gradle.properties | 1 - versions/1.21.4/settings.gradle | 10 - .../impl/cosmetics/CloakFeatureRenderer.java | 459 ------------------ .../impl/cosmetics/HatFeatureRenderer.java | 39 -- .../impl/cosmetics/obj/MtlLoader.java | 56 --- .../impl/cosmetics/obj/ObjModel.java | 102 ---- .../impl/cosmetics/obj/ObjRenderer.java | 112 ----- .../impl/cosmetics/utils/IdentifierUtils.java | 68 --- .../impl/cosmetics/utils/ShaderUtils.java | 41 -- .../entity/CameraOverriddenEntity.java | 11 - .../features/entity/EntityFeatureImpl.java | 79 --- .../features/entity/HealthRenderState.java | 24 - .../features/mixins/entity/CameraMixin.java | 46 -- .../features/mixins/entity/EntityMixin.java | 62 --- .../features/mixins/misc/NametagsMixin.java | 95 ---- .../render/BackgroundRendererMixin.java | 21 - .../mixins/render/GameRendererMixin.java | 41 -- .../render/LightmapTextureManagerMixin.java | 35 -- .../render/LivingEntityRenderStateMixin.java | 60 --- .../render/LivingEntityRendererMixin.java | 51 -- .../features/mixins/render/RenderMixin.java | 85 ---- .../impl/features/mixins/world/TpsMixin.java | 30 -- .../features/network/NetworkFeatureImpl.java | 37 -- .../features/player/PlayerFeatureImpl.java | 253 ---------- .../features/render/RenderFeatureImpl.java | 64 --- .../impl/features/world/WorldFeatureImpl.java | 36 -- .../impl/mixins/IdentifierMixin.java | 13 - .../impl/mixins/ItemStackMixin.java | 19 - .../impl/mixins/MatrixStackMixin.java | 50 -- .../impl/mixins/MinecraftClientMixin.java | 162 ------- .../impl/mixins/QuaternionfMixin.java | 9 - .../saturnclient/impl/mixins/SpriteMixin.java | 9 - .../impl/mixins/StatusEffectMixin.java | 44 -- .../saturnclient/impl/mixins/TextMixin.java | 24 - .../saturnclient/impl/mixins/WindowMixin.java | 22 - .../impl/provider/FeatureProviderFabric.java | 68 --- .../impl/provider/GLFWProviderImpl.java | 18 - .../impl/provider/RefConstructorImpl.java | 25 - .../impl/provider/SaturnProviderImpl.java | 71 --- .../impl/ui/EntityDrawerImpl.java | 85 ---- .../saturnclient/impl/ui/RenderScopeImpl.java | 407 ---------------- .../impl/ui/SaturnScreenFabric.java | 163 ------- .../saturnclient/SaturnClient.java | 64 --- .../saturnclient/event/KeyInputHandler.java | 54 --- .../mixin/DrawContextAccessor.java | 12 - .../saturnclient/mixin/NameTagMixin.java | 93 ---- .../mixin/PlayerEntityRendererMixin.java | 30 -- .../saturnclient/mixin/SetScreenMixin.java | 27 -- .../mixin/SplashOverlayMixin.java | 161 ------ .../saturnclient/mixin/TabListMixin.java | 49 -- .../saturnclient/mixin/WhoAmI.java | 32 -- .../1.21.4/src/main/resources/fabric.mod.json | 28 -- .../src/main/resources/features.mixins.json | 21 - .../src/main/resources/impl.mixins.json | 20 - .../main/resources/saturnclient.mixins.json | 17 - 70 files changed, 128 insertions(+), 4076 deletions(-) delete mode 100755 scripts/port.sh delete mode 100644 versions/1.21.4/build.gradle delete mode 100644 versions/1.21.4/settings.gradle delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/TextMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/SaturnClient.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java delete mode 100644 versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java delete mode 100644 versions/1.21.4/src/main/resources/fabric.mod.json delete mode 100644 versions/1.21.4/src/main/resources/features.mixins.json delete mode 100644 versions/1.21.4/src/main/resources/impl.mixins.json delete mode 100644 versions/1.21.4/src/main/resources/saturnclient.mixins.json diff --git a/README.MD b/README.MD index d98683c..c0c8aab 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.5) +./gradlew :1.21.11:build # a single version ./gradlew :1.21.11:runClient # launch a development client ``` @@ -65,7 +65,7 @@ We welcome contributions of all kinds: If you're an artist or designer interested in helping with cosmetics or visual assets, we'd love to collaborate. -Most features belong in `common`, which every Minecraft version shares. For code that differs between versions, see the [version guide](VERSION_GUIDE.md): it covers how the versions are laid out, porting a change to all of them with `scripts/port.sh`, and adding a new Minecraft version. Every pull request is compiled for all versions automatically. +Most features belong in `common`, which every Minecraft version shares. For code that differs between versions, see the [version guide](VERSION_GUIDE.md): it covers how the versions share one copy of the code with Stonecutter, writing version-specific code, and adding a new Minecraft version. Every pull request is compiled for all versions automatically. ## Credits diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index ce4dcac..6f45e2e 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -4,13 +4,13 @@ How Saturn Client supports several Minecraft versions, and how to change or add ## Layout -Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: +Every supported Minecraft version (1.21.4 to 1.21.11) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/): - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.6 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 and 1.21.5), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs), one copy for every version. Where Minecraft's API differs between versions, the code goes behind version comments (see below). +- `versions//`: each version's `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), plus its `build/` and `run/` folders. Each version is the Gradle project `:`. -`settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. +`settings.gradle.kts` lists the versions in `stonecutterVersions`. The root `build.gradle.kts` builds each version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version is `loom_version` in the root `gradle.properties`. ## Version-specific code with Stonecutter @@ -48,36 +48,21 @@ Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` The `emotes` repository uses the same setup, and its `BentCubeRenderer` and `PlayerModelMixin` are small examples of version comments. -## Porting a change to the other versions +## Checking a change on every version -Make the change in one version, usually the newest, then run: - -```sh -scripts/port.sh # port uncommitted changes to every other version -scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.4,1.21.5 # only some versions -scripts/port.sh --commit # port what a commit changed instead -``` - -The script applies the diff under one version's source to each other version with `git apply --3way`. The Stonecutter `src/` counts as one version (1.21.11), so changes port between it and the old copies in both directions: - -- **applied**: the files matched, and nothing else is needed. -- **CONFLICTS**: that version's code really differs. The file gets normal conflict markers, with the version's own code in `ours` and the ported change in `theirs`. Adapt the change to that version's API and resolve. -- **already has this change**: nothing to do, which is safe to see when re-running. - -Only source is ported. `build.gradle` and `gradle.properties` are version-specific on purpose. Then build everything: +Since every version shares `src/`, a change applies to all of them at once. Code that uses the Minecraft API may still only compile on some, so build them all: ```sh ./gradlew compileJava ``` -The **Check** workflow runs the same compile on every pull request, so a version that was missed or mis-ported fails before merging. +The **Check** workflow runs the same compile on every pull request, so a version a change doesn't compile on fails before merging. Mixins whose target changed fail at startup rather than at compile time, so launch the versions a change touches with `./gradlew ::runClient`. + +For bigger changes, `./gradlew buildAll` builds every version's jar into `build/allJars/`. ## Adding a Minecraft version -Add new versions to Stonecutter rather than copying a folder: - 1. Create `versions//gradle.properties` with `minecraft_version`, `yarn_mappings`, `loader_version` and `fabric_api_version` (copy 1.21.11's and change the values; they're listed at ). Loom's version is shared, in the root `gradle.properties`. -2. Add `` to `stonecutterVersions` in `settings.gradle.kts`. When moving an existing `mc-` version over instead, delete its `versions//src` and run `./gradlew ::clean` once: the new project shares the old one's `build/` folder, and classes compiled from the removed sources would otherwise end up in the jar. +2. Add `` to `stonecutterVersions` in `settings.gradle.kts`. 3. Build it with `./gradlew ::compileJava` and put what Minecraft changed behind version comments. Check the mixin configs in `src/main/resources/*.mixins.json` as well: a mixin whose target changed fails at startup, not at compile time, so launch it with `./gradlew ::runClient`. 4. The release workflow builds everything through `buildAll`, and "Publish to Modrinth" takes the game version from each jar's name, so neither needs changing. diff --git a/gradle.properties b/gradle.properties index 947409b..8b55dd0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,5 +11,5 @@ mod_version=0.1.1-beta # Saturn's emote library (git.selimaj.dev/saturnclientmc/emotes) emotes_version=0.1.0 -# Loom, for the Stonecutter versions (settings.gradle.kts). Old mc- projects set their own. +# Loom, for every Minecraft version (read in settings.gradle.kts). loom_version=1.17.21 diff --git a/scripts/port.sh b/scripts/port.sh deleted file mode 100755 index 2715fd5..0000000 --- a/scripts/port.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env bash -# Port a change made in one Minecraft version's code to the other versions. -# -# Takes the diff under one version's source folder and applies it to the others -# with `git apply --3way`: it applies cleanly where the files match, and leaves -# normal merge conflicts only where a version really differs. Only source is -# ported; build.gradle and gradle.properties are version-specific on purpose. -# -# Versions moved to Stonecutter (stonecutterVersions in settings.gradle.kts) -# share the top-level src/, which counts as one version: the active one set in -# stonecutter.gradle.kts. The others keep their own copy in versions//src. -# -# Usage: -# scripts/port.sh [--from VERSION] [--to V1,V2,...] [--commit REV] [--dry-run] -# -# --from version the change was made in. Default: the only version with -# uncommitted changes (or changed by --commit). -# --to comma-separated versions to port to. Default: all others. -# --commit port the changes a commit made instead of uncommitted changes. -# --dry-run report what would happen without changing anything. -# -# Exit status: 0 if every version applied cleanly (or already had the change), -# 1 if any version has conflicts or failed. - -set -euo pipefail - -cd "$(git rev-parse --show-toplevel)" - -from="" -to="" -commit="" -dry_run=false - -while [ $# -gt 0 ]; do - case "$1" in - --from) from="$2"; shift 2 ;; - --to) to="$2"; shift 2 ;; - --commit) commit="$2"; shift 2 ;; - --dry-run) dry_run=true; shift ;; - -h|--help) sed -n '2,23p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; - *) echo "Unknown option: $1 (see --help)" >&2; exit 2 ;; - esac -done - -# Versions sharing the Stonecutter src/, and the one that stands for them. -stonecutter_versions=$(sed -n 's/^val stonecutterVersions = listOf(\(.*\))/\1/p' settings.gradle.kts | tr -d '" ' | tr ',' ' ') -stonecutter_active=$(sed -n 's/^stonecutter active "\(.*\)"/\1/p' stonecutter.gradle.kts 2>/dev/null || true) - -is_stonecutter() { - printf '%s\n' $stonecutter_versions | grep -qx "$1" -} - -# Where a version's source lives. -src_of() { - if is_stonecutter "$1"; then echo "src"; else echo "versions/$1/src"; fi -} - -old_versions=$(for d in versions/*/; do [ -d "$d/src" ] && basename "$d"; done) -all_versions=$(printf '%s\n' $old_versions $stonecutter_active | grep . | sort -t. -k1,1n -k2,2n -k3,3n) - -version_exists() { - [ -d "$(src_of "$1")" ] -} - -# Versions with changes, from the working tree or from the given commit. -changed_versions() { - if [ -n "$commit" ]; then - git show --name-only --format= "$commit" -- versions/ src/ - else - git diff HEAD --name-only -- versions/ src/ - git ls-files --others --exclude-standard -- versions/ src/ - fi | sed -n -e 's#^versions/\([^/]*\)/src/.*#\1#p' -e "s#^src/.*#${stonecutter_active}#p" | sort -u -} - -if [ -z "$from" ]; then - candidates=$(changed_versions) - count=$(printf '%s\n' "$candidates" | grep -c . || true) - if [ "$count" -ne 1 ]; then - echo "Changes found in ${count} versions (${candidates//$'\n'/, }); pass --from to choose one." >&2 - exit 2 - fi - from="$candidates" -fi - -version_exists "$from" || { echo "No such version: $from" >&2; exit 2; } -if is_stonecutter "$from"; then - from="$stonecutter_active" -fi -from_src=$(src_of "$from") - -if [ -z "$to" ]; then - to=$(printf '%s\n' $all_versions | grep -vx "$from" | paste -sd, -) -fi - -# New files are only included in `git diff HEAD` once git knows about them. -if [ -z "$commit" ]; then - untracked=$(git ls-files --others --exclude-standard -- "$from_src") - if [ -n "$untracked" ]; then - if $dry_run; then - echo "note: new files in $from_src are untracked and won't be ported in a dry run:" >&2 - printf ' %s\n' $untracked >&2 - else - printf '%s\n' "$untracked" | xargs git add --intent-to-add -- - fi - fi -fi - -# --full-index gives --3way the real blob ids to merge against. -if [ -n "$commit" ]; then - patch=$(git show --full-index --binary --format= "$commit" -- "$from_src") -else - patch=$(git diff HEAD --full-index --binary -- "$from_src") -fi - -if [ -z "$patch" ]; then - echo "No changes under $from_src to port." >&2 - exit 2 -fi - -files=$(printf '%s\n' "$patch" | grep -c '^diff --git' || true) -echo "Porting $files file(s) from $from${commit:+ (commit $commit)}" - -from_re=$(printf '%s' "$from_src" | sed 's/\./\\./g') -tmp=$(mktemp -d) -trap 'rm -rf "$tmp"' EXIT - -status=0 -IFS=',' read -r -a targets <<< "$to" - -for target in "${targets[@]}"; do - if [ "$target" = "$from" ]; then - continue - fi - if is_stonecutter "$target" && [ "$target" != "$stonecutter_active" ]; then - printf ' %-8s skipped: shares src/ with %s\n' "$target" "$stonecutter_active" - [ "$from" = "$stonecutter_active" ] || status=1 - continue - fi - if ! version_exists "$target"; then - printf ' %-8s skipped: no such version\n' "$target" - status=1 - continue - fi - - # Point the patch's file headers at the target version's source folder. - target_src=$(src_of "$target") - printf '%s\n' "$patch" | sed -E "/^(diff --git |--- |\+\+\+ |rename (from|to) |copy (from|to) )/ s#([ab]/|(from|to) )${from_re}/#\1${target_src}/#g" > "$tmp/$target.patch" - - if git apply --check --reverse "$tmp/$target.patch" 2>/dev/null; then - printf ' %-8s already has this change\n' "$target" - continue - fi - - if $dry_run; then - if git apply --check "$tmp/$target.patch" 2>/dev/null; then - printf ' %-8s would apply cleanly\n' "$target" - else - printf ' %-8s would need a 3-way merge (possible conflicts)\n' "$target" - fi - continue - fi - - if output=$(git apply --3way "$tmp/$target.patch" 2>&1); then - printf ' %-8s applied\n' "$target" - else - conflicts=$(git diff --name-only --diff-filter=U -- "$target_src") - if [ -n "$conflicts" ]; then - printf ' %-8s CONFLICTS in:\n' "$target" - printf '%s\n' "$conflicts" | sed 's/^/ /' - else - printf ' %-8s FAILED:\n' "$target" - printf '%s\n' "$output" | sed 's/^/ /' - fi - status=1 - fi -done - -if ! $dry_run; then - echo - echo "Ported changes are staged in the target versions. Resolve any conflicts, then build" - echo "the affected versions, e.g. ./gradlew compileJava" -fi - -exit $status diff --git a/settings.gradle.kts b/settings.gradle.kts index b32f1a3..4167ee7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,8 +6,7 @@ pluginManagement { mavenCentral() } - // Loom's version, for the Stonecutter versions' build.gradle.kts (the old mc- projects set - // their own in versions//gradle.properties). + // Loom's version for build.gradle.kts, which can't read properties in its plugins block. val loom_version: String by settings plugins { id("net.fabricmc.fabric-loom-remap") version loom_version @@ -24,7 +23,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { @@ -32,12 +31,3 @@ stonecutter { vcsVersion = "1.21.11" } } - -// Versions not moved to Stonecutter yet still build from their own copy in versions//src, -// as projects named mc-. -file("versions").listFiles { file -> file.isDirectory && file.name !in stonecutterVersions }!! - .sortedBy { it.name } - .forEach { dir -> - include("mc-${dir.name}") - project(":mc-${dir.name}").projectDir = dir - } diff --git a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java index 9891052..68196f0 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java @@ -41,8 +41,11 @@ public class HatFeatureRenderer extends FeatureRenderer=1.21.5 { ModelPart head = this.getContextModel().head; matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); + //?} else + //this.getContextModel().head.rotate(matrices); ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), matrices, output, light, diff --git a/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java index bd8be2d..d35ceae 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java @@ -43,9 +43,12 @@ public class IdentifierUtils { } SaturnClient.client.execute(() -> { + //? if >=1.21.5 { NativeImageBackedTexture texture = new NativeImageBackedTexture( () -> identifier.toString(), nativeImage); + //?} else + //NativeImageBackedTexture texture = new NativeImageBackedTexture(nativeImage); SaturnClient.client.getTextureManager().registerTexture(identifier, texture); }); diff --git a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java index 0038258..99fb441 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java @@ -3,10 +3,17 @@ package org.saturnclient.impl.cosmetics.utils; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.cosmetics.utils.GifUtils; +//? if >=1.21.5 import com.mojang.blaze3d.pipeline.RenderPipeline; +//? if >=1.21.5 import net.minecraft.client.gl.RenderPipelines; import net.minecraft.client.render.RenderLayer; +//? if <1.21.5 { +/*import net.minecraft.client.render.RenderPhase; +import net.minecraft.client.render.VertexFormat.DrawMode; +import net.minecraft.client.render.VertexFormats; +*///?} //? if >=1.21.11 { import net.minecraft.client.render.RenderLayers; import net.minecraft.client.render.RenderSetup; @@ -18,6 +25,8 @@ import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; import net.minecraft.util.Identifier; public class ShaderUtils { + // Render pipelines exist from 1.21.5; before that the layer names a shader program directly. + //? if >=1.21.5 { public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) @@ -25,6 +34,7 @@ public class ShaderUtils { .withShaderDefine("PORTAL_LAYERS", 16) .withCull(false) .build()); + //?} //? if >=1.21.11 { public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", @@ -38,13 +48,29 @@ public class ShaderUtils { .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) .build(false)); - *///?} else { + *///?} else if >=1.21.5 { /*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, END_GATEWAY_PIPELINE, RenderLayer.MultiPhaseParameters.builder() .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false) .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false).build()) .build(false)); + *///?} else { + /*public static final RenderLayer END_GATEWAY = RenderLayer.of( + "end_gateway", + VertexFormats.POSITION, + DrawMode.QUADS, + 1536, + false, + false, + RenderLayer.MultiPhaseParameters.builder() + .program(RenderLayer.END_GATEWAY_PROGRAM) + .texture(Textures.create() + .add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false) + .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false) + .build()) + .cull(RenderPhase.DISABLE_CULLING) + .build(false)); *///?} public static RenderLayer getRenderLayer(IdentifierRef texture) { diff --git a/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java index c6d97f3..82ccd2c 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java @@ -2,6 +2,7 @@ package org.saturnclient.impl.features.mixins.render; import net.minecraft.client.render.GameRenderer; +import org.saturnclient.mod.mods.FreelookMod; import org.saturnclient.mod.mods.ZoomMod; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -32,6 +33,9 @@ public class GameRendererMixin { if (ZoomMod.shouldZoom()) { float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); cir.setReturnValue(zoomedFov); + } else if (FreelookMod.shouldZoomOut()) { + float zoomedFov = cir.getReturnValue() / FreelookMod.getZoomLevel(); + cir.setReturnValue(zoomedFov); } } } diff --git a/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java index a161cd6..0cc9f98 100644 --- a/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ b/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java @@ -169,22 +169,34 @@ public class PlayerFeatureImpl implements PlayerFeature { @Override public ItemStackRef getHelmet() { + //? if >=1.21.5 { return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); + //?} else + //return wrap(hasPlayer() ? player().getInventory().armor.get(3) : ItemStack.EMPTY); } @Override public ItemStackRef getChestplate() { + //? if >=1.21.5 { return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); + //?} else + //return wrap(hasPlayer() ? player().getInventory().armor.get(2) : ItemStack.EMPTY); } @Override public ItemStackRef getLeggings() { + //? if >=1.21.5 { return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); + //?} else + //return wrap(hasPlayer() ? player().getInventory().armor.get(1) : ItemStack.EMPTY); } @Override public ItemStackRef getBoots() { + //? if >=1.21.5 { return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); + //?} else + //return wrap(hasPlayer() ? player().getInventory().armor.get(0) : ItemStack.EMPTY); } // --------------------------------------------------------------- diff --git a/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java index dd47753..ae9427a 100644 --- a/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java @@ -3,8 +3,11 @@ package org.saturnclient.impl.mixins; import net.minecraft.client.util.math.MatrixStack; import org.spongepowered.asm.mixin.Mixin; //? if <1.21.6 { -/*import org.joml.Quaternionfc; -import org.saturnclient.common.ref.render.MatrixStackRef; +/*import org.saturnclient.common.ref.render.MatrixStackRef; +//? if >=1.21.5 +import org.joml.Quaternionfc; +//? if <1.21.5 +//import org.joml.Quaternionf; import org.spongepowered.asm.mixin.Shadow; import net.minecraft.util.math.RotationAxis; *///?} @@ -30,10 +33,16 @@ import net.minecraft.util.math.RotationAxis; public abstract void scale(float x, float y, float z); @Shadow + //? if >=1.21.5 public abstract void multiply(Quaternionfc quaternion); + //? if <1.21.5 + //public abstract void multiply(Quaternionf quaternion); @Shadow + //? if >=1.21.5 public abstract void multiply(Quaternionfc quaternion, float originX, float originY, float originZ); + //? if <1.21.5 + //public abstract void multiply(Quaternionf quaternion, float originX, float originY, float originZ); @Override public void translate(float x, float y) { diff --git a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index ebbe007..d58ba85 100644 --- a/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -104,13 +104,19 @@ public class EntityDrawerImpl implements EntityDrawer { float k = entity.bodyYaw; float l = entity.getYaw(); float m = entity.getPitch(); + //? if >=1.21.5 float n = entity.lastHeadYaw; + //? if <1.21.5 + //float n = entity.prevHeadYaw; float o = entity.headYaw; entity.setYaw(angle); entity.bodyYaw = angle; entity.setPitch(-(j * 20.0F)); entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); + //? if >=1.21.5 entity.lastHeadYaw = entity.getHeadYaw(); + //? if <1.21.5 + //entity.prevHeadYaw = entity.getHeadYaw(); entity.setCustomNameVisible(false); float p = entity.getScale(); @@ -122,7 +128,10 @@ public class EntityDrawerImpl implements EntityDrawer { entity.bodyYaw = k; entity.setYaw(l); entity.setPitch(m); + //? if >=1.21.5 entity.lastHeadYaw = n; + //? if <1.21.5 + //entity.prevHeadYaw = n; entity.headYaw = o; renderScope.disableScissor(); } @@ -136,7 +145,10 @@ public class EntityDrawerImpl implements EntityDrawer { scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); scopeImpl.matrices.multiply(quaternionf); scopeImpl.draw(); + //? if >=1.21.5 DiffuseLighting.disableGuiDepthLighting(); + //? if <1.21.5 + //DiffuseLighting.method_34742(); EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); entityRenderDispatcher.setRenderShadows(false); diff --git a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index fbba7b2..3cdb564 100644 --- a/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -400,7 +400,10 @@ import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; +//? if >=1.21.5 import net.minecraft.item.ItemDisplayContext; +//? if <1.21.5 +//import net.minecraft.item.ModelTransformationMode; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; @@ -645,6 +648,8 @@ public class RenderScopeImpl implements RenderScope { matrices.push(); matrices.scale(0.25f, 0.25f, 1.0f); + //? if <1.21.5 + //RenderSystem.setShaderTexture(0, sprite); RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); Matrix4f matrix4f = matrices.peek().getPositionMatrix(); VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); @@ -673,40 +678,42 @@ public class RenderScopeImpl implements RenderScope { if (stack.isEmpty()) return; - SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, - seed); + //? if >=1.21.5 + SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed); + //? if >=1.21.5 + SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed); + //? if <1.21.5 + //SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ModelTransformationMode.GUI, false, world, entity, seed); - if (!stack.isEmpty()) { - SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - this.matrices.push(); - this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z)); + this.matrices.push(); + //? if >=1.21.5 + this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z)); + //? if <1.21.5 + //this.matrices.translate(x + 8, y + 8, 150 + (itemRenderState.hasDepth() ? z : 0)); - try { - this.matrices.scale(16.0F, -16.0F, 16.0F); - boolean bl = !this.itemRenderState.isSideLit(); - if (bl) { - this.draw(); - DiffuseLighting.disableGuiDepthLighting(); - } - - this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); + try { + this.matrices.scale(16.0F, -16.0F, 16.0F); + boolean bl = !this.itemRenderState.isSideLit(); + if (bl) { this.draw(); - if (bl) { - DiffuseLighting.enableGuiDepthLighting(); - } - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); + DiffuseLighting.disableGuiDepthLighting(); } - this.matrices.pop(); + this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); + this.draw(); + if (bl) { + DiffuseLighting.enableGuiDepthLighting(); + } + } catch (Throwable throwable) { + CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); + CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); + crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); + crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); + crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); + throw new CrashException(crashReport); } + + this.matrices.pop(); } // ---------------------------- diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index 63fe7d5..672f1e4 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -88,11 +88,12 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { if (postEffectProcessor != null) { float radius = screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f); - postEffectProcessor.render( - this.client.getFramebuffer(), - this.pool, - pass -> pass.setUniform("Radius", radius) - ); + //? if >=1.21.5 + postEffectProcessor.render(this.client.getFramebuffer(), this.pool, pass -> pass.setUniform("Radius", radius)); + //? if <1.21.5 + //postEffectProcessor.setUniforms("Radius", radius); + //? if <1.21.5 + //postEffectProcessor.render(this.client.getFramebuffer(), this.pool); } *///?} diff --git a/versions/1.21.4/build.gradle b/versions/1.21.4/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.4/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.4/gradle.properties b/versions/1.21.4/gradle.properties index 0e59b54..fc841d3 100644 --- a/versions/1.21.4/gradle.properties +++ b/versions/1.21.4/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.4 yarn_mappings=1.21.4+build.8 loader_version=0.18.4 -loom_version=1.17.21 # Mod Properties maven_group=org.saturnclient diff --git a/versions/1.21.4/settings.gradle b/versions/1.21.4/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.4/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index 2725e32..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,459 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, - PlayerEntityRenderState playerEntityRenderState, float f, float g) { - if (playerEntityRenderState.invisible || !playerEntityRenderState.capeVisible - || playerEntityRenderState.skinTextures.capeTexture() != null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(playerEntityRenderState.name); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - VertexConsumer vertexConsumer = vertexConsumerProvider - .getBuffer(ShaderUtils.getRenderLayer(customCape)); - - matrixStack.push(); - - matrixStack.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) { - matrixStack.translate(0.0F, -0.053125F, 0.06875F); - } - - if (playerEntityRenderState.isInSneakingPose) { - matrixStack.translate(0, 0.16f, 0.0f); - matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, playerEntityRenderState.field_53537 / 108.0f); - float rawVelY = playerEntityRenderState.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, playerEntityRenderState.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - horizontalCurve = MathHelper.clamp(playerEntityRenderState.field_53537 / 150.0f, -1.0f, 1.0f); - - renderCape(matrixStack.peek(), vertexConsumer, playerEntityRenderState, light, OverlayTexture.DEFAULT_UV); - - matrixStack.pop(); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index f5a723d..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - SaturnPlayer player = SaturnPlayer.get(state.name); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - this.getContextModel().head.rotate(matrices); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index 7b9c20d..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture(nativeImage); - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 0cb9ba9..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase; -import net.minecraft.client.render.VertexFormat.DrawMode; -import net.minecraft.client.render.VertexFormats; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderLayer END_GATEWAY = RenderLayer.of( - "end_gateway", - VertexFormats.POSITION, - DrawMode.QUADS, - 1536, - false, - false, - RenderLayer.MultiPhaseParameters.builder() - .program(RenderLayer.END_GATEWAY_PROGRAM) - .texture(Textures.create() - .add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false, false) - .build()) - .cull(RenderPhase.DISABLE_CULLING) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -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 net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java deleted file mode 100644 index 8c1763d..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/misc/NametagsMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.saturnclient.impl.features.mixins.misc; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; - -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.render.LivingEntityRenderStateMixin; -import org.saturnclient.mod.mods.NametagsMod; -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; - -/** - * Intercepts nametag rendering and replaces the displayed text with - * the string produced by {@link NametagsMod#getNametagString}. - * - * Key changes from the original: - * - *
    - *
  • The old {@code NametagsFabric.EntityStateImpl} bridge class is - * replaced by {@link EntityFeatureImpl.RenderStateEntityState}, - * which wraps the {@link HealthRenderState} already injected into - * the render state by {@link LivingEntityRenderStateMixin}.
  • - *
  • The feature import changes from {@code Nametags} to - * {@link NametagsMod}; the two static methods - * ({@code shouldReplaceName} / {@code getNametagString}) are - * unchanged in signature.
  • - *
  • The entity's display name is extracted from the render state's - * {@code nameVisible} / text fields where available, falling back - * to the plain text string passed to this method.
  • - *
- * - * The re-entrancy guard ({@code saturn$rendering}) is kept intact to - * prevent infinite recursion when we call {@code renderLabelIfPresent} - * with the replacement text. - */ -@Mixin(EntityRenderer.class) -public abstract class NametagsMixin { - - /** Guards against the recursive call we make with the replacement text. */ - @Unique - private static final ThreadLocal saturn$rendering = ThreadLocal.withInitial(() -> false); - - @Shadow - protected abstract void renderLabelIfPresent( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light); - - @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true) - private void saturn$replaceNametag( - S state, Text text, - MatrixStack matrices, VertexConsumerProvider vertexConsumers, - int light, CallbackInfo ci) { - - // Skip our own recursive call - if (saturn$rendering.get()) - return; - - if (!NametagsMod.shouldReplaceName()) - return; - - // Only living entities carry health data - if (!(state instanceof LivingEntityRenderState living)) - return; - if (!(living instanceof HealthRenderState hrs)) - return; - - // Build the platform-neutral EntityState from the render-state snapshot - // (health/type were written by LivingEntityRendererMixin at extract time). - String customName = text != null ? text.getString() : null; - EntityFeatureImpl.RenderStateEntityState entityState = new EntityFeatureImpl.RenderStateEntityState( - customName, hrs); - - // Ask the feature for the replacement string - String replacement = NametagsMod.getNametagString(entityState); - if (replacement == null) - return; // feature decided not to replace this entity - - ci.cancel(); - saturn$rendering.set(true); - try { - renderLabelIfPresent(state, Text.literal(replacement), matrices, vertexConsumers, light); - } finally { - saturn$rendering.set(false); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index a9f641a..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.BackgroundRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(BackgroundRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index 82ccd2c..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.mod.mods.ZoomMod; -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; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } else if (FreelookMod.shouldZoomOut()) { - float zoomedFov = cir.getReturnValue() / FreelookMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 2f24b25..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.Mod.Mods.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the Mod's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index bbb293b..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.saturnclient.impl.features.mixins.misc.NametagsMixin; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -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; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index 124dc4f..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -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; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl( - context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairMod) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -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; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index 0261f80..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,253 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getInventory().armor.get(3) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getInventory().armor.get(2) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getInventory().armor.get(1) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getInventory().armor.get(0) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java deleted file mode 100644 index 1850b50..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.math.RotationAxis; - -@Mixin(MatrixStack.class) -public abstract class MatrixStackMixin implements MatrixStackRef { - @Shadow - public abstract void push(); - - @Shadow - public abstract void pop(); - - @Shadow - public abstract void translate(float x, float y, float z); - - @Shadow - public abstract void scale(float x, float y, float z); - - @Shadow - public abstract void multiply(Quaternionf quaternion); - - @Shadow - public abstract void multiply(Quaternionf quaternion, float originX, float originY, float originZ); - - @Override - public void translate(float x, float y) { - translate(x, y, 0); - } - - @Override - public void scale(float x, float y) { - scale(x, y, 1.0f); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle), originX, originY, originZ); - } - - @Override - public void rotate(float angle) { - multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle)); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index b0a269a..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().getName(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().getId(); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index a164eae..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return (SpriteRef) SaturnClient.client - .getStatusEffectSpriteManager() - .getSprite(getEffectType()); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 3e1a8b8..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont((Identifier) (Object) font))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index 77c8da3..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, - float mouseX, - float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { - float g = (float) (x1 + x2) / 2.0F; - float h = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(0, 6, x2, y2); - float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); - float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); - float k = entity.bodyYaw; - float l = entity.getYaw(); - float m = entity.getPitch(); - float n = entity.prevHeadYaw; - float o = entity.headYaw; - entity.setYaw(angle); - entity.bodyYaw = angle; - entity.setPitch(-(j * 20.0F)); - entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); - entity.prevHeadYaw = entity.getHeadYaw(); - entity.setCustomNameVisible(false); - - float p = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); - float q = (float) size / p; - drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity); - - entity.setCustomNameVisible(true); - entity.bodyYaw = k; - entity.setYaw(l); - entity.setPitch(m); - entity.prevHeadYaw = n; - entity.headYaw = o; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, - Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - if (renderScope instanceof RenderScopeImpl scopeImpl) { - scopeImpl.matrices.push(); - scopeImpl.matrices.translate((double) x, (double) y, 0); - scopeImpl.matrices.scale(size, size, -size); - scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); - scopeImpl.matrices.multiply(quaternionf); - scopeImpl.draw(); - DiffuseLighting.method_34742(); - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - - entityRenderDispatcher.setRenderShadows(false); - scopeImpl.draw((vertexConsumers) -> { - entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - scopeImpl.matrices, vertexConsumers, 15728880); - }); - - scopeImpl.draw(); - entityRenderDispatcher.setRenderShadows(true); - scopeImpl.getMatrixStack().pop(); - DiffuseLighting.enableGuiDepthLighting(); - } - - } - - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, - negativeAngle); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index 80061ca..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,407 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; -import java.util.function.Consumer; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; - -import com.mojang.blaze3d.systems.RenderSystem; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.render.DiffuseLighting; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.ItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.util.Window; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ModelTransformationMode; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - // ---------------------------- - // Fields - // ---------------------------- - public MatrixStack matrices; - public VertexConsumerProvider.Immediate vertexConsumers; - private ScissorStack scissorStack = new ScissorStack(); - private int opacity = 255 << 24; - private final ItemRenderState itemRenderState; - - // ---------------------------- - // Constructors - // ---------------------------- - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); - } - - public RenderScopeImpl(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) { - this.matrices = matrices; - this.vertexConsumers = vertexConsumers; - this.scissorStack = new ScissorStack(); - this.itemRenderState = new ItemRenderState(); - } - - // ---------------------------- - // Matrix & Transform - // ---------------------------- - @Override - public MatrixStackRef getMatrixStack() { - return (MatrixStackRef) matrices; - } - - // ---------------------------- - // Color & Opacity - // ---------------------------- - @Override - public void setOpacity(float alpha) { - this.opacity = (int) (alpha * 255) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - // ---------------------------- - // Draw / Window Info - // ---------------------------- - @Override - public void draw() { - this.vertexConsumers.draw(); - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - public void draw(Consumer drawer) { - drawer.accept(this.vertexConsumers); - this.vertexConsumers.draw(); - } - - // ---------------------------- - // Shapes - // ---------------------------- - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x1 < x2) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y1 < y2) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); - vertexConsumer.vertex(matrix4f, x1, y1, 0).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, 0).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, 0).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, 0).color(color); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - fill(x1, y1, x2, y2, 0, color); - } - - public void fill(int x1, int y1, int x2, int y2, int z, int color) { - fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { - fill(layer, x1, y1, x2, y2, 0, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - if (x1 < x2) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y1 < y2) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); - vertexConsumer.vertex(matrix4f, x1, y1, z).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, z).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, z).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, z).color(color); - } - - @Override - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - // ---------------------------- - // Text - // ---------------------------- - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int i = 0; - for (String line : text.split("\n")) { - color = getColor(color); - matrices.push(); - matrices.translate(x, y + i * Fonts.getHeight(), 0); - matrices.scale(scale, scale, 1.0f); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - textRenderer.draw((Text) Fonts.setFont(line, font), 0, font == 0 ? 1 : 7, color, false, - matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, 15728880); - matrices.pop(); - i++; - } - } - - // ---------------------------- - // Textures & Sprites - // ---------------------------- - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0.0f) / textureWidth, (u + regionWidth) / textureWidth, - (v + 0.0f) / textureHeight, (v + regionHeight) / textureHeight, color); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { - Sprite sprite = (Sprite) saturnSprite; - if (color == 0) - return; - if (width != 0 && height != 0) { - drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, - sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color); - } - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg((IdentifierRef) (Object) sprite, (x2 - x1) * 2, - (y2 - y1) * 2); - } - if (color == 0) - return; - - x1 *= 4; - x2 *= 4; - y1 *= 4; - y2 *= 4; - color = getColor(color); - - matrices.push(); - matrices.scale(0.25f, 0.25f, 1.0f); - RenderSystem.setShaderTexture(0, sprite); - RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); - vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(u1, v1).color(color); - vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(u1, v2).color(color); - vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(u2, v2).color(color); - vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(u2, v1).color(color); - matrices.pop(); - } - - // ---------------------------- - // Items - // ---------------------------- - @Override - public void drawItem(ItemStackRef item, int x, int y) { - drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (stack.isEmpty()) - return; - - SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ModelTransformationMode.GUI, - false, world, entity, seed); - - matrices.push(); - matrices.translate(x + 8, y + 8, 150 + (itemRenderState.hasDepth() ? z : 0)); - - try { - matrices.scale(16.0f, -16.0f, 16.0f); - boolean disableLighting = !itemRenderState.isSideLit(); - if (disableLighting) { - draw(); - DiffuseLighting.disableGuiDepthLighting(); - } - - itemRenderState.render(matrices, vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); - draw(); - - if (disableLighting) - DiffuseLighting.enableGuiDepthLighting(); - } catch (Throwable e) { - CrashReport crashReport = CrashReport.create(e, "Rendering item"); - CrashReportSection section = crashReport.addElement("Item being rendered"); - section.add("Item Type", () -> String.valueOf(stack.getItem())); - section.add("Item Components", () -> String.valueOf(stack.getComponents())); - section.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - - matrices.pop(); - } - - // ---------------------------- - // Scissor / Clipping - // ---------------------------- - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect screenRect = new ScreenRect(x1, y1, x2 - x1, y2 - y1) - .transform(matrices.peek().getPositionMatrix()); - setScissor(scissorStack.push(screenRect)); - } - - @Override - public void disableScissor() { - setScissor(scissorStack.pop()); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.containsPoint(x, y); - } - - private void setScissor(@Nullable ScreenRect rect) { - draw(); - if (rect != null) { - Window window = SaturnClient.client.getWindow(); - int framebufferHeight = window.getFramebufferHeight(); - double scaleFactor = window.getScaleFactor(); - RenderSystem.enableScissor( - (int) (rect.getLeft() * scaleFactor), - (int) (framebufferHeight - rect.getBottom() * scaleFactor), - Math.max(0, (int) (rect.width() * scaleFactor)), - Math.max(0, (int) (rect.height() * scaleFactor))); - } else { - RenderSystem.disableScissor(); - } - } - - static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect p_281812_) { - ScreenRect screenrectangle = this.stack.peekLast(); - if (screenrectangle != null) { - ScreenRect screenrectangle1 = Objects.requireNonNullElse(p_281812_.intersection(screenrectangle), - ScreenRect.empty()); - this.stack.addLast(screenrectangle1); - return screenrectangle1; - } else { - this.stack.addLast(p_281812_); - return p_281812_; - } - } - - @Nullable - public ScreenRect pop() { - if (this.stack.isEmpty()) { - throw new IllegalStateException("Scissor stack underflow"); - } else { - this.stack.removeLast(); - return this.stack.peekLast(); - } - } - - public boolean containsPoint(int p_329411_, int p_333404_) { - return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 9f21dcd..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.PostEffectProcessor; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.render.DefaultFramebufferSet; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.client.util.Pool; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - private final Pool pool = new Pool(3); - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - - // Force upload each texture to GPU - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @SuppressWarnings("deprecation") - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, screen.backgroundOpacity, delta); - } - - PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( - Identifier.ofVanilla("blur"), - DefaultFramebufferSet.MAIN_ONLY); - - if (postEffectProcessor != null) { - postEffectProcessor.setUniforms("Radius", screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f)); - postEffectProcessor.render(this.client.getFramebuffer(), this.pool); - } - - // We are using a Abstracted RenderScope because older minecraft versions don't - // use DrawContext - RenderScope renderScope = new RenderScopeImpl(context.getMatrices(), - ((DrawContextAccessor) context).getVertexConsumers()); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (screen.mouseClicked(mouseX, mouseY, button)) { - return true; - } - - return super.mouseClicked(mouseX, mouseY, button); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { - if (screen.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)) { - return true; - } - - return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); - } - - @Override - public boolean mouseReleased(double mouseX, double mouseY, int button) { - if (screen.mouseReleased(mouseX, mouseY, button)) { - return true; - } - - return super.mouseReleased(mouseX, mouseY, button); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - if (screen.keyPressed(keyCode, scanCode, modifiers)) { - return true; - } - - return super.keyPressed(keyCode, scanCode, modifiers); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - // ------------------------------------------ - // ScreenProvider implementations - // ------------------------------------------ - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index 4e037c7..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final String KEY_CATEGORY = "key.category.saturnclient"; - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding( - MAIN_MENU_KEY_ID, - InputUtil.Type.KEYSYM, - DEFAULT_MENU_KEY, - KEY_CATEGORY)); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow().getHandle(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index f049e40..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.VertexConsumerProvider; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("vertexConsumers") - VertexConsumerProvider.Immediate getVertexConsumers(); -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java deleted file mode 100644 index 518494c..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.font.TextRenderer.TextLayerType; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderDispatcher; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.Vec3d; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.saturnclient.SaturnClient; - -import java.util.UUID; - -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(value = EntityRenderer.class, priority = 1800) -public abstract class NameTagMixin { - @Shadow - public EntityRenderDispatcher dispatcher; - - /** - * @author HexLeo - * @reason Adds the Saturn Client icon to the player's name if they are online - * with Saturn Client - */ - @Inject(method = "renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"), cancellable = true) - private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - - UUID uuid = isSaturn(state); - - if (uuid != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid))); - - Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); - - renderLabel(state, iconText.append(nameText), matrices, - vertexConsumers, light); - - ci.cancel(); - } - } - - private UUID isSaturn(S state) { - if (state instanceof PlayerEntityRenderState) { - String name = ((PlayerEntityRenderState) state).name; - SaturnPlayer player = SaturnPlayer.get(name); - if (player != null) { - return player.uuid; - } - } - - return null; - } - - private void renderLabel(S state, Text text, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light) { - Vec3d vec3d = state.nameLabelPos; - if (vec3d != null) { - boolean bl = !state.sneaking; - int i = "deadmau5".equals(text.getString()) ? -10 : 0; - matrices.push(); - matrices.translate(vec3d.x, vec3d.y + 0.5, vec3d.z); - matrices.multiply(this.dispatcher.getRotation()); - matrices.scale(0.025F, -0.025F, 0.025F); - Matrix4f matrix4f = matrices.peek().getPositionMatrix(); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - float f = (float) (-textRenderer.getWidth(text)) / 2.0F; - int j = (int) (SaturnClient.client.options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24; - textRenderer.draw(text, f, (float) i, -2130706433, false, matrix4f, vertexConsumers, - bl ? TextLayerType.SEE_THROUGH : TextLayerType.NORMAL, j, light); - if (bl) { - textRenderer.draw(text, f, (float) i, -1, false, matrix4f, vertexConsumers, TextLayerType.NORMAL, 0, - light); - } - matrices.pop(); - } - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 0363dad..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -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.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -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(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index ecc4823..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 2a68cd6..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -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 com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.getName(); - UUID uuid = profile.getId(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.4/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.4/src/main/resources/fabric.mod.json b/versions/1.21.4/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.4/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.4/src/main/resources/features.mixins.json b/versions/1.21.4/src/main/resources/features.mixins.json deleted file mode 100644 index 8d3c331..0000000 --- a/versions/1.21.4/src/main/resources/features.mixins.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "misc.NametagsMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.4/src/main/resources/impl.mixins.json b/versions/1.21.4/src/main/resources/impl.mixins.json deleted file mode 100644 index 094792b..0000000 --- a/versions/1.21.4/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MatrixStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.4/src/main/resources/saturnclient.mixins.json b/versions/1.21.4/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.4/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} From a8e6f14022104cdc9c248076f250ae1730d0e135 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 27 Sep 2026 06:48:57 +0200 Subject: [PATCH 10/10] Fix the Release workflow's comment on how buildAll remaps Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 275c4d9..1f1f194 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -57,7 +57,8 @@ jobs: - name: Build all versions run: | chmod +x gradlew - # buildAll remaps every versions/* project in parallel into build/allJars. + # buildAll remaps every Minecraft version (two at a time, to stay within the + # Gradle heap) into build/allJars. ./gradlew buildAll --no-daemon --stacktrace - name: Upload jars to the release