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 106a746..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.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 4935949..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,19 +34,43 @@ public class ShaderUtils { .withShaderDefine("PORTAL_LAYERS", 16) .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 { + //?} 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 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/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/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/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 60% 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..ae9427a 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,25 @@ 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.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; +*///?} +/** + * 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(); @@ -22,10 +33,16 @@ public abstract class MatrixStackMixin implements MatrixStackRef { 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) { @@ -46,4 +63,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..d58ba85 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,100 @@ 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(); + //? 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(); + 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); + //? if >=1.21.5 + entity.lastHeadYaw = n; + //? if <1.21.5 + //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(); + //? if >=1.21.5 + DiffuseLighting.disableGuiDepthLighting(); + //? if <1.21.5 + //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/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 70807b9..3cdb564 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,423 @@ 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; +//? 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; +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); + //? if <1.21.5 + //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; + + //? 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); + + 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); + 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..672f1e4 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,29 @@ 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); + //? 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); + } + *///?} + 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.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 - } -} 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 - } -}