diff --git a/README.MD b/README.MD index 30050ed..dcb50ac 100644 --- a/README.MD +++ b/README.MD @@ -47,7 +47,7 @@ git clone --recurse-submodules https://git.selimaj.dev/saturnclientmc/saturnclie cd saturnclient ./gradlew buildAll # every version → build/allJars/ -./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.9) +./gradlew :1.21.11:build # a single version (versions not on Stonecutter yet: :mc-1.21.8) ./gradlew :1.21.11:runClient # launch a development client ``` diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index cccbfe8..ac9d7ed 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -7,8 +7,8 @@ How Saturn Client supports several Minecraft versions, and how to change or add Saturn is moving from one full copy of the version-specific code per Minecraft version to a single copy built with [Stonecutter](https://stonecutter.kikugie.dev/) (issue #8). During the move there are two kinds of version: - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. -- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.10 and 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. -- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.9), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. +- `src/`: the version-specific code (providers, refs, mixins and the three mixin configs) for the versions built by Stonecutter, currently **1.21.9 to 1.21.11**. It's one copy: where Minecraft's API differs between them, the code goes behind version comments (see below). Each of these versions is the Gradle project `:`, and `versions//` holds only its `gradle.properties` (Minecraft, Yarn, Fabric Loader and Fabric API versions), `build/` and `run/`. +- `versions//src/`: the versions not moved yet (1.21.4 to 1.21.8), each a full copy, as the Gradle project `:mc-` with its own `build.gradle`. `settings.gradle.kts` lists the Stonecutter versions in `stonecutterVersions` and includes every other folder under `versions/` as `:mc-`. The root `build.gradle.kts` builds each Stonecutter version, and `stonecutter.gradle.kts` configures the root project (shared repositories, the `common` wiring and `buildAll`). Loom's version for the Stonecutter versions is `loom_version` in the root `gradle.properties`. @@ -51,7 +51,7 @@ Make the change in one version, usually the newest, then run: ```sh scripts/port.sh # port uncommitted changes to every other version scripts/port.sh --dry-run # see what would apply cleanly first -scripts/port.sh --to 1.21.8,1.21.9 # only some versions +scripts/port.sh --to 1.21.7,1.21.8 # only some versions scripts/port.sh --commit # port what a commit changed instead ``` diff --git a/settings.gradle.kts b/settings.gradle.kts index 99e7a84..3f592e3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // Versions built by Stonecutter from the shared src/ (see stonecutter.gradle.kts). Each one's // versions//gradle.properties holds its Minecraft, Yarn and Fabric API versions. -val stonecutterVersions = listOf("1.21.10", "1.21.11") +val stonecutterVersions = listOf("1.21.9", "1.21.10", "1.21.11") stonecutter { create(rootProject) { diff --git a/versions/1.21.9/build.gradle b/versions/1.21.9/build.gradle deleted file mode 100644 index b40015c..0000000 --- a/versions/1.21.9/build.gradle +++ /dev/null @@ -1,101 +0,0 @@ -plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" - id 'maven-publish' -} - -version = "${project.mod_version}+${project.minecraft_version}" -group = project.maven_group - -base { - archivesName = project.archives_base_name -} - -repositories { - maven { name = "Selimaj"; url = 'https://git.selimaj.dev/api/packages/selimaj-dev/maven' } -} - -dependencies { - // To change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" - - // Saturn's emote library (limb bending, Emotecraft emotes) - include modImplementation("org.saturnclient:emotes-fabric:${project.emotes_version}+${project.minecraft_version}") - - implementation project(":common") - - include implementation("dev.selimaj:session-java:0.2.0") - include implementation("de.javagl:obj:0.4.0") - include implementation("com.formdev:svgSalamander:1.1.4") - include implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-annotations:2.17.0") - include implementation("com.fasterxml.jackson.core:jackson-core:2.17.0") -} - -/* - * ================================================================ - * Resource Processing - * ================================================================ - * Injects version values into fabric.mod.json. - */ -processResources { - inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version - inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" - - filesMatching("fabric.mod.json") { - expand( - "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version - ) - } -} - -tasks.withType(JavaCompile).configureEach { - it.options.release = 21 -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() - - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} - -jar { - inputs.property "archivesName", project.base.archivesName - - from("LICENSE") { - rename { "${it}_${inputs.properties.archivesName}"} - } - - from project(":common").sourceSets.main.output - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// configure the maven publication -publishing { - publications { - create("mavenJava", MavenPublication) { - artifactId = project.archives_base_name - from components.java - } - } - - // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. - repositories { - // Add repositories to publish to here. - // Notice: This block does NOT have the same function as the block in the top level. - // The repositories here will be used for publishing your artifact, not for - // retrieving dependencies. - } -} \ No newline at end of file diff --git a/versions/1.21.9/gradle.properties b/versions/1.21.9/gradle.properties index 5335436..7387155 100644 --- a/versions/1.21.9/gradle.properties +++ b/versions/1.21.9/gradle.properties @@ -10,7 +10,6 @@ org.gradle.configuration-cache=false minecraft_version=1.21.9 yarn_mappings=1.21.9+build.1 loader_version=0.19.0 -loom_version=1.17.21 fabric_api_version=0.134.1+1.21.9 diff --git a/versions/1.21.9/settings.gradle b/versions/1.21.9/settings.gradle deleted file mode 100644 index 75c4d72..0000000 --- a/versions/1.21.9/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - mavenCentral() - gradlePluginPortal() - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java deleted file mode 100644 index b13e942..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ /dev/null @@ -1,462 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import java.util.Arrays; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.config.Config; -import org.saturnclient.cosmetics.Cloaks; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; -import org.saturnclient.saturnclient.SaturnRenderState; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.equipment.EquipmentModel; -import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; -import net.minecraft.client.render.entity.equipment.EquipmentModel.LayerType; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.EquippableComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.equipment.EquipmentAsset; -import net.minecraft.registry.RegistryKey; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RotationAxis; -import net.minecraft.util.math.Vec3d; - -/** - * The cloak renderer - * - **Efficient**: uses a image only consisting of the cloak texture, 16x8 - * whitespace. - * - **Curving**: Curves when player velocity increases. - * - **Wavey**: Makes the cloak feel like wind, when jump sprinting. - */ -public class CloakFeatureRenderer extends FeatureRenderer { - private final EquipmentModelLoader equipmentModelLoader; - private static final int PARTS = 24; - private final float[] segmentValues = new float[PARTS]; - private static final int H_PARTS = 6; - private float horizontalCurve = 0.0f; - - private static final float TEX_W = 176f; - private static final float TEX_H = 138f; - - private static final class PxRect { - final int x, y, w, h; - - PxRect(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - float u1() { - return x / TEX_W; - } - - float v1() { - return y / TEX_H; - } - - float u2() { - return (x + w) / TEX_W; - } - - float v2() { - return (y + h) / TEX_H; - } - } - - private static final PxRect FRONT_RECT = new PxRect(8, 8, 80, 128); - private static final PxRect BACK_RECT = new PxRect(96, 8, 80, 128); - private static final PxRect LEFT_EDGE_RECT = new PxRect(0, 8, 8, 128); - private static final PxRect RIGHT_EDGE_RECT = new PxRect(88, 8, 8, 128); - private static final PxRect TOP_RECT = new PxRect(8, 0, 80, 8); - private static final PxRect BOTTOM_RECT = new PxRect(88, 0, 80, 8); - - public CloakFeatureRenderer(FeatureRendererContext context, - EquipmentModelLoader equipmentModelLoader) { - super(context); - this.equipmentModelLoader = equipmentModelLoader; - Arrays.fill(segmentValues, 0.0f); - } - - private boolean hasCustomModelForLayer(ItemStack stack, EquipmentModel.LayerType layerType) { - EquippableComponent equippableComponent = (EquippableComponent) stack - .get(DataComponentTypes.EQUIPPABLE); - if (equippableComponent != null && !equippableComponent.assetId().isEmpty()) { - EquipmentModel equipmentModel = this.equipmentModelLoader - .get((RegistryKey) equippableComponent.assetId().get()); - return !equipmentModel.getLayers(layerType).isEmpty(); - } else { - return false; - } - } - - private void vertex(VertexConsumer vc, Matrix4f posMat, Matrix3f normalMat, - Vec3d pos, int color, - float u, float v, int overlay, int light, - float nx, float ny, float nz) { - - Vector4f p = new Vector4f((float) pos.x, (float) pos.y, (float) pos.z, 1.0f); - p.mul(posMat); - - Vector3f n = new Vector3f(nx, ny, nz); - n.mul(normalMat); - - vc.vertex( - p.x(), p.y(), p.z(), - color, - u, v, - overlay, light, - n.x(), n.y(), n.z()); - } - - private void renderCapeQuad(VertexConsumer vertexConsumer, MatrixStack.Entry entry, - Vec3d bottomLeft, Vec3d bottomRight, Vec3d topRight, Vec3d topLeft, - float u1, float v1, float u2, float v2, int light, int overlay, - float normalX, float normalY, float normalZ, boolean flipWinding) { - // Extract matrix (you must transform positions manually now) - Matrix4f pos = entry.getPositionMatrix(); - Matrix3f normalMat = entry.getNormalMatrix(); - - int color = 0xFFFFFFFF; // white RGBA - - if (!flipWinding) { - // CCW - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - } else { - // CW - vertex(vertexConsumer, pos, normalMat, topLeft, color, u1, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, topRight, color, u2, v1, overlay, light, normalX, normalY, normalZ); - vertex(vertexConsumer, pos, normalMat, bottomRight, color, u2, v2, overlay, light, normalX, normalY, - normalZ); - vertex(vertexConsumer, pos, normalMat, bottomLeft, color, u1, v2, overlay, light, normalX, normalY, - normalZ); - } - } - - private void renderCape(MatrixStack.Entry entry, VertexConsumer vertexConsumer, - PlayerEntityRenderState playerState, int light, int overlay) { - - float capeWidth = 10.0f / 16.0f; - float capeHeight = 16.0f / 16.0f; - float capeDepth = 1.0f / 16.0f; - - final float frontU1 = FRONT_RECT.u1(); - final float frontU2 = FRONT_RECT.u2(); - final float frontV1 = FRONT_RECT.v1(); - final float frontV2 = FRONT_RECT.v2(); - final float frontPartV = (frontV2 - frontV1) / PARTS; - - final float backU1 = BACK_RECT.u1(); - final float backU2 = BACK_RECT.u2(); - final float backV1 = BACK_RECT.v1(); - final float backV2 = BACK_RECT.v2(); - final float backPartV = (backV2 - backV1) / PARTS; - - final float leftU1 = LEFT_EDGE_RECT.u1(); - final float leftU2 = LEFT_EDGE_RECT.u2(); - final float leftV1 = LEFT_EDGE_RECT.v1(); - final float leftV2 = LEFT_EDGE_RECT.v2(); - final float leftPartV = (leftV2 - leftV1) / PARTS; - - final float rightU1 = RIGHT_EDGE_RECT.u1(); - final float rightU2 = RIGHT_EDGE_RECT.u2(); - final float rightV1 = RIGHT_EDGE_RECT.v1(); - final float rightV2 = RIGHT_EDGE_RECT.v2(); - final float rightPartV = (rightV2 - rightV1) / PARTS; - - final float topU1 = TOP_RECT.u1(); - final float topU2 = TOP_RECT.u2(); - final float topV1 = TOP_RECT.v1(); - final float topV2 = TOP_RECT.v2(); - - final float bottomU1 = BOTTOM_RECT.u1(); - final float bottomU2 = BOTTOM_RECT.u2(); - final float bottomV1 = BOTTOM_RECT.v1(); - final float bottomV2 = BOTTOM_RECT.v2(); - - // ============================= - // 1. Spine - // ============================= - - float[] spineY = new float[PARTS + 1]; - float[] spineZ = new float[PARTS + 1]; - - float partHeight = capeHeight / PARTS; - - for (int i = 0; i < PARTS; i++) { - float angle = (2.0f - segmentValues[i]) * ((float) Math.PI / 2f); - float dirY = -(float) Math.cos(angle); - float dirZ = (float) Math.sin(angle); - - spineY[i + 1] = spineY[i] + dirY * partHeight; - spineZ[i + 1] = spineZ[i] + dirZ * partHeight; - } - - // ============================= - // 2. Grid - // ============================= - - Vec3d[][] inner = new Vec3d[H_PARTS + 1][PARTS + 1]; - Vec3d[][] outer = new Vec3d[H_PARTS + 1][PARTS + 1]; - - for (int x = 0; x <= H_PARTS; x++) { - - float t = (float) x / H_PARTS; - float xPos = -capeWidth / 2.0f + capeWidth * t; - - float centered = t - 0.5f; - float curve = (centered * centered) * 0.3f; - float zCurve = (curve * horizontalCurve) / PARTS; - - for (int i = 0; i <= PARTS; i++) { - float y = spineY[i]; - float z = spineZ[i]; - - int idx = Math.min(i, PARTS - 1); - // angle: 0 is horizontal (y-flat), PI/2 is vertical (z-flat) - float angle = (2.0f - segmentValues[idx]) * ((float) Math.PI / 2f); - - float cosA = (float) Math.cos(angle); - float sinA = (float) Math.sin(angle); - - // Calculate how much the horizontal curve shifts the vertex - float currentCurve = zCurve * i; - - // Rotate the curve offset so it aligns with the cape's tilt - float curveY = sinA * currentCurve; - float curveZ = cosA * currentCurve; - - float thickY = sinA * capeDepth; - float thickZ = cosA * capeDepth; - - inner[x][i] = new Vec3d(xPos, y - curveY, z - curveZ); - outer[x][i] = new Vec3d(xPos, (y - curveY) - thickY, (z - curveZ) - thickZ); - } - - } - - // ============================= - // 3. Front + Back - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - float uStart = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) x / H_PARTS)); - float uEnd = frontU1 + (frontU2 - frontU1) * (1.0f - ((float) (x + 1) / H_PARTS)); - - float buStart = backU1 + (backU2 - backU1) * ((float) x / H_PARTS); - float buEnd = backU1 + (backU2 - backU1) * ((float) (x + 1) / H_PARTS); - - for (int i = 0; i < PARTS; i++) { - - float vStart = frontV1 + frontPartV * i; - float vEnd = frontV1 + frontPartV * (i + 1); - - float bvStart = backV1 + backPartV * i; - float bvEnd = backV1 + backPartV * (i + 1); - - Vec3d innerTL = inner[x + 1][i]; - Vec3d innerTR = inner[x][i]; - Vec3d innerBL = inner[x + 1][i + 1]; - Vec3d innerBR = inner[x][i + 1]; - - Vec3d outerTL = outer[x + 1][i]; - Vec3d outerTR = outer[x][i]; - Vec3d outerBL = outer[x + 1][i + 1]; - Vec3d outerBR = outer[x][i + 1]; - - // FRONT - renderCapeQuad(vertexConsumer, entry, - outerBR, outerBL, outerTL, outerTR, - uStart, vStart, uEnd, vEnd, - light, overlay, 0, 0, 1, false); - - // BACK - renderCapeQuad(vertexConsumer, entry, - innerBL, innerBR, innerTR, innerTL, - buEnd, bvStart, buStart, bvEnd, - light, overlay, 0, 0, -1, false); - } - } - - // ============================= - // 4. LEFT SIDE (x = H_PARTS) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[H_PARTS][i]; - Vec3d innerBot = inner[H_PARTS][i + 1]; - Vec3d outerTop = outer[H_PARTS][i]; - Vec3d outerBot = outer[H_PARTS][i + 1]; - - float vStart = leftV1 + leftPartV * i; - float vEnd = leftV1 + leftPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - innerTop, outerTop, outerBot, innerBot, - leftU1, vEnd, - leftU2, vStart, - light, overlay, -1, 0, 0, false); - } - - // ============================= - // 5. RIGHT SIDE (x = 0) - // ============================= - - for (int i = 0; i < PARTS; i++) { - - Vec3d innerTop = inner[0][i]; - Vec3d innerBot = inner[0][i + 1]; - Vec3d outerTop = outer[0][i]; - Vec3d outerBot = outer[0][i + 1]; - - float vStart = rightV1 + rightPartV * i; - float vEnd = rightV1 + rightPartV * (i + 1); - - renderCapeQuad(vertexConsumer, entry, - outerTop, innerTop, innerBot, outerBot, - rightU1, vEnd, - rightU2, vStart, - light, overlay, 1, 0, 0, false); - } - - // ============================= - // 6. TOP (i = 0) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d outerL = outer[x][0]; - Vec3d outerR = outer[x + 1][0]; - Vec3d innerR = inner[x + 1][0]; - Vec3d innerL = inner[x][0]; - - float uStart = topU1 + (topU2 - topU1) * ((float) x / H_PARTS); - float uEnd = topU1 + (topU2 - topU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - outerL, outerR, innerR, innerL, - uStart, topV1, uEnd, topV2, - light, overlay, 0, 1, 0, false); - } - - // ============================= - // 7. BOTTOM (i = PARTS) - // ============================= - - for (int x = 0; x < H_PARTS; x++) { - - Vec3d innerL = inner[x][PARTS]; - Vec3d innerR = inner[x + 1][PARTS]; - Vec3d outerR = outer[x + 1][PARTS]; - Vec3d outerL = outer[x][PARTS]; - - float uStart = bottomU1 + (bottomU2 - bottomU1) * ((float) x / H_PARTS); - float uEnd = bottomU1 + (bottomU2 - bottomU1) * ((float) (x + 1) / H_PARTS); - - renderCapeQuad(vertexConsumer, entry, - innerL, innerR, outerR, outerL, - uStart, bottomV1, uEnd, bottomV2, - light, overlay, 0, -1, 0, false); - } - } - - // Shift array left and insert new value at the start - private void updateSegmentValues(float value) { - // Shift all elements one position to the right (from end to start) - for (int i = segmentValues.length - 1; i > 0; i--) { - segmentValues[i] = segmentValues[i - 1]; - } - - // Insert the new value at index 0 - segmentValues[0] = value; - } - - private long lastUpdate = 0; - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - if (state.invisible || !state.capeVisible - || state.skinTextures.cape() != null) { - return; - } - - SaturnPlayer player = state.getData(SaturnRenderState.saturnDataKey); - - if (player == null) { - return; - } - - IdentifierRef customCape = Cloaks.getCurrentCloakTexture(player.cloak); - if (customCape == null - || this.hasCustomModelForLayer(state.equippedChestStack, LayerType.WINGS)) { - return; - } - - int minBrightness = 7; - int blockLight = (light >> 4) & 0xF; - int skyLight = (light >> 20) & 0xF; - blockLight = Math.max(blockLight, minBrightness); - skyLight = Math.max(skyLight, minBrightness); - light = (skyLight << 20) | (blockLight << 4); - - matrices.push(); - - matrices.translate(0.0f, 0.0f, 0.12f); - - if (this.hasCustomModelForLayer(state.equippedChestStack, LayerType.HUMANOID)) { - matrices.translate(0.0F, -0.053125F, 0.06875F); - } - - if (state.isInSneakingPose) { - matrices.translate(0, 0.16f, 0.0f); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f)); - } - - long now = System.currentTimeMillis(); - if (now - lastUpdate >= 20) { - float velX = Math.min(0.8f, state.field_53537 / 108.0f); - float rawVelY = state.field_53536; - float velY = (rawVelY > 3.4f ? rawVelY : rawVelY < -3.4f ? rawVelY : 0.0f) / 16; - - float value = Math.max(0.0f, Math.min(2.0f, state.isSwimming ? 0.0f : velX + velY)); - - if (Config.cloakPhysics.value) { - updateSegmentValues(segmentValues[0] + (value - segmentValues[0]) * 0.3f); - } else { - Arrays.fill(segmentValues, segmentValues[0] + (value - segmentValues[0]) * 0.05f); - } - lastUpdate = now; - } - - final int l = light; - - horizontalCurve = MathHelper.clamp(state.field_53537 / 150.0f, -1.0f, 1.0f); - - queue.submitCustom(matrices, ShaderUtils.getRenderLayer(customCape), (entry, vertexConsumer) -> { - renderCape(entry, vertexConsumer, state, l, OverlayTexture.DEFAULT_UV); - }); - - matrices.pop(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java deleted file mode 100644 index 35110ec..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/HatFeatureRenderer.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.cosmetics; - -import org.joml.Quaternionf; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.obj.MtlLoader; -import org.saturnclient.impl.cosmetics.obj.ObjModel; - -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.command.OrderedRenderCommandQueue; -import net.minecraft.client.render.entity.feature.FeatureRenderer; -import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.model.ModelPart; - -public class HatFeatureRenderer extends FeatureRenderer { - public HatFeatureRenderer(FeatureRendererContext context) { - super(context); - } - - // @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - PlayerEntityRenderState state, float limbAngle, float limbDistance) { - if (state.displayName == null) - return; - - SaturnPlayer player = SaturnPlayer.get(state.displayName.getString()); - - if (state.invisible || player == null || player.hat.isEmpty()) { - return; - } - - matrices.push(); - - ModelPart head = this.getContextModel().head; - matrices.multiply(new Quaternionf().rotationZYX(head.roll, head.yaw, head.pitch)); - - ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat), - matrices, vertexConsumers, light, - OverlayTexture.DEFAULT_UV); - - matrices.pop(); - } - - @Override - public void render(MatrixStack matrices, OrderedRenderCommandQueue queue, int light, PlayerEntityRenderState state, - float limbAngle, float limbDistance) { - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java deleted file mode 100644 index 11b06d3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/MtlLoader.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; - -public class MtlLoader { - static Map> loadedMtls = new HashMap<>(); - - static Map loadMtl(Identifier mtlId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(mtlId).get().getInputStream()) { - List mtlList = MtlReader.read(is); - Map mtlMap = new java.util.LinkedHashMap<>(); - for (Mtl mtl : mtlList) { - mtlMap.put(mtl.getName(), mtl); - } - return mtlMap; - } - } - - public static Map of(Identifier mtlId) { - if (loadedMtls.containsKey(mtlId)) - return loadedMtls.get(mtlId); - - try { - Map mtl = loadMtl(mtlId); - loadedMtls.put(mtlId, mtl); - - return mtl; - } catch (IOException e) { - e.printStackTrace(); - - return null; - } - - } - - public static Map cosmetic(String cosmeticId) { - int index = cosmeticId.indexOf('_'); - - String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1); - - if (mtlId.isEmpty()) - mtlId = "white"; - - return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl")); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java deleted file mode 100644 index 3e7237e..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; - -import de.javagl.obj.Mtl; -import de.javagl.obj.Obj; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.Resource; -import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Identifier; - -public class ObjModel { - private static final ObjectMapper MAPPER = new ObjectMapper(); - public static final Map loadedObjModels = new HashMap<>(); - - public record Config( - @JsonProperty("translate") Vec3d transform, - @JsonProperty("scale") Vec3d scale, - @JsonProperty("rotation") Vec3d rotation) { - - public Config { - transform = transform == null ? new Vec3d(0, 0, 0) : transform; - scale = scale == null ? new Vec3d(1, 1, 1) : scale; - rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation; - } - - @JsonFormat(shape = JsonFormat.Shape.ARRAY) - public record Vec3d(float x, float y, float z) { - } - } - - Obj obj; - Config config; - - public static ObjModel cosmetic(String cosmeticKind, String id) { - return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model")); - } - - public static ObjModel of(Identifier obj) { - if (loadedObjModels.containsKey(obj)) - return loadedObjModels.get(obj); - - ObjModel o = new ObjModel(obj); - loadedObjModels.put(obj, o); - return o; - } - - ObjModel(Identifier identifier) { - Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj"); - Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json"); - - try { - this.obj = ObjRenderer.loadObj(objId); - } catch (IOException e) { - e.printStackTrace(); - } - - // Try loading JSON config if it exists - ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager(); - Optional resource = resourceManager.getResource(jsonId); - - if (resource.isPresent()) { - try (InputStream stream = resource.get().getInputStream()) { - this.config = MAPPER.readValue(stream, Config.class); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void render(Map mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - int overlay) { - matrices.push(); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f)); - - if (this.config != null) { - matrices.translate(config.transform.x, config.transform.y, config.transform.z); - - matrices.scale(config.scale.x, config.scale.y, config.scale.z); - - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y)); - matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z)); - } - - ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay); - - matrices.pop(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java deleted file mode 100644 index 97498cc..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.saturnclient.impl.cosmetics.obj; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.impl.cosmetics.utils.ShaderUtils; - -import de.javagl.obj.*; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.Identifier; - -public class ObjRenderer { - - public static Obj loadObj(Identifier objId) throws IOException { - try (InputStream is = MinecraftClient.getInstance().getResourceManager() - .getResource(objId).get().getInputStream()) { - return ObjReader.read(is); - } - } - - public static void renderObj(Obj obj, Map mtlMap, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay) { - MatrixStack.Entry entry = matrices.peek(); - - Map materialGroups = ObjSplitting.splitByMaterialGroups(obj); - - for (Map.Entry group : materialGroups.entrySet()) { - String materialName = group.getKey(); - Obj groupObj = group.getValue(); - - Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null; - - // Resolve texture identifier using same logic as ObjUnbakedModelModel - IdentifierRef texture = IdentifierRef.ofVanilla("textures/misc/white.png"); - - if (mtl != null) { - String mapKd = mtl.getMapKd(); - if (mapKd != null) { - if (!mapKd.startsWith("#")) { - texture = IdentifierRef.of(mapKd); - } - } - } - - // Diffuse color (Kd) - float r = 1f, g = 1f, b = 1f; - if (mtl != null) { - FloatTuple kd = mtl.getKd(); - if (kd != null) { - r = kd.getX(); - g = kd.getY(); - b = kd.getZ(); - } - } - - VertexConsumer consumer = vertexConsumers.getBuffer(ShaderUtils.getRenderLayer(texture)); - - int faces = groupObj.getNumFaces(); - final float fr = r, fg = g, fb = b; - - for (int f = 0; f < faces; f++) { - ObjFace face = groupObj.getFace(f); - int verts = face.getNumVertices(); - - // Your original winding order logic, untouched - for (int i = verts - 1; i >= 0; i--) { - writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb); - } - } - } - } - - private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer, - MatrixStack.Entry matrix, int light, int overlay, - float r, float g, float b) { - - FloatTuple pos = obj.getVertex(face.getVertexIndex(index)); - float x = pos.getX(); - float y = pos.getY(); - float z = pos.getZ(); - - float nx = 0f, ny = 1f, nz = 0f; - int normalIndex = face.getNormalIndex(index); - if (normalIndex >= 0) { - FloatTuple n = obj.getNormal(normalIndex); - nx = n.getX(); - ny = n.getY(); - nz = n.getZ(); - } - - float u = 0f, v = 0f; - int texIndex = face.getTexCoordIndex(index); - if (texIndex >= 0) { - FloatTuple tc = obj.getTexCoord(texIndex); - u = tc.getX(); - v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left - } - - consumer.vertex(matrix, x, y, z) - .color(r, g, b, 1f) - .texture(u, v) - .overlay(overlay) - .light(light) - .normal(matrix, nx, ny, nz); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java deleted file mode 100644 index bd8be2d..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/IdentifierUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.saturnclient.SaturnClient; - -import net.minecraft.client.texture.NativeImage; -import net.minecraft.client.texture.NativeImageBackedTexture; -import net.minecraft.util.Identifier; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.util.Map; - -public class IdentifierUtils { - - public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) { - try { - Identifier identifier = (Identifier) (Object) identifierRef; - - int width = bufferedImage.getWidth(); - int height = bufferedImage.getHeight(); - - NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false); - - if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) { - int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData(); - - int index = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, pixels[index++]); - } - } - - } else { - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y)); - } - } - - } - - SaturnClient.client.execute(() -> { - NativeImageBackedTexture texture = new NativeImageBackedTexture( - () -> identifier.toString(), - nativeImage); - - SaturnClient.client.getTextureManager().registerTexture(identifier, texture); - }); - - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e); - } - } - - public static void registerBufferedImageTexturesBulk(Map textures) { - - long start = System.currentTimeMillis(); - - textures.forEach(IdentifierUtils::registerBufferedImageTextureFast); - - long end = System.currentTimeMillis(); - - SaturnClient.LOGGER.info( - "Registered {} textures in {}ms", - textures.size(), - (end - start)); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java deleted file mode 100644 index 2e8ec23..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.saturnclient.impl.cosmetics.utils; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.cosmetics.utils.GifUtils; - -import com.mojang.blaze3d.pipeline.RenderPipeline; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderPhase.Textures; -import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer; -import net.minecraft.util.Identifier; - -public class ShaderUtils { - public static final RenderPipeline END_GATEWAY_PIPELINE = RenderPipelines.register( - RenderPipeline.builder(new RenderPipeline.Snippet[] { RenderPipelines.RENDERTYPE_END_PORTAL_SNIPPET }) - .withLocation("pipeline/end_gateway") - .withShaderDefine("PORTAL_LAYERS", 16) - .withCull(false) - .build()); - - public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false, - END_GATEWAY_PIPELINE, - RenderLayer.MultiPhaseParameters.builder() - .texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false) - .add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build()) - .build(false)); - - public static RenderLayer getRenderLayer(IdentifierRef texture) { - String path = texture.toString(); - if (path.endsWith(".gif")) { - return RenderLayer.getEntityAlpha((Identifier) (Object) GifUtils.get(texture)); - } else if (path.endsWith("end.png")) { - return END_GATEWAY; - } else { - return RenderLayer.getEntityAlpha((Identifier) (Object) texture); - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java deleted file mode 100644 index 310b69d..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/CameraOverriddenEntity.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.impl.features.entity; - -public interface CameraOverriddenEntity { - float freelook$getCameraPitch(); - - float freelook$getCameraYaw(); - - void freelook$setCameraPitch(float pitch); - - void freelook$setCameraYaw(float yaw); -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java deleted file mode 100644 index 901542e..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/EntityFeatureImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.entity.LivingEntity; - -/** - * Fabric implementation of {@link EntityFeature}. - * - * Crosshair targeting is resolved via {@link MinecraftClient#crosshairTarget}. - * Entity state for nametag rendering is supplied at render time by - * {@link org.saturnclient.modules.mixins.LivingEntityRendererMixin} which - * writes into the render state; {@link NametagsMixin} then constructs - * a {@link RenderStateEntityState} from the already-extracted snapshot. - */ -public class EntityFeatureImpl implements EntityFeature { - - private final MinecraftClient mc; - - public EntityFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean isTargetingLivingEntity() { - HitResult target = mc.crosshairTarget; - if (target == null || target.getType() != HitResult.Type.ENTITY) - return false; - Entity hit = ((EntityHitResult) target).getEntity(); - return hit instanceof LivingEntity; - } - - // --------------------------------------------------------------- - // Render-state adapter - // --------------------------------------------------------------- - - /** - * Wraps a {@link HealthRenderState} (already injected into the - * Minecraft render-state object) as a platform-neutral - * {@link EntityState} for use by {@link NametagsFeature}. - * - * This is constructed inside {@link NametagsMixin} where both the - * render-state mixin interface and the entity name are available. - */ - public static final class RenderStateEntityState implements EntityState { - - private final String customName; - private final HealthRenderState hrs; - - public RenderStateEntityState(String customName, HealthRenderState hrs) { - this.customName = customName; - this.hrs = hrs; - } - - @Override - public String getCustomName() { - return customName; - } - - @Override - public float getHealth() { - return hrs.saturn$getHealth(); - } - - @Override - public float getMaxHealth() { - return hrs.saturn$getMaxHealth(); - } - - @Override - public EntityType getEntityType() { - return hrs.saturn$getEntityType(); - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java deleted file mode 100644 index 7c62f81..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/entity/HealthRenderState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.saturnclient.impl.features.entity; - -import org.saturnclient.common.feature.EntityFeature; - -/** - * Injected interface on - * {@link net.minecraft.client.render.entity.state.LivingEntityRenderState}. - * - * Carries the entity's health snapshot and classification into the render - * pipeline so that {@link NametagsMixin} can read them without touching - * the live entity again. - */ -public interface HealthRenderState { - - float saturn$getHealth(); - - float saturn$getMaxHealth(); - - void saturn$setHealth(float health, float maxHealth); - - EntityFeature.EntityType saturn$getEntityType(); - - void saturn$setEntityType(EntityFeature.EntityType type); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java deleted file mode 100644 index e1ff321..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/CameraMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.Camera; -import net.minecraft.entity.Entity; -import net.minecraft.world.BlockView; - -@Mixin(Camera.class) -public abstract class CameraMixin { - @Unique - boolean firstTime = true; - - @Shadow - protected abstract void setRotation(float yaw, float pitch); - - @Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER)) - public void lockRotation(BlockView focusedBlock, Entity cameraEntity, boolean isThirdPerson, boolean isFrontFacing, - float tickDelta, CallbackInfo ci) { - if (FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - CameraOverriddenEntity cameraOverriddenEntity = (CameraOverriddenEntity) cameraEntity; - - if (firstTime && SaturnClient.client.player != null) { - cameraOverriddenEntity.freelook$setCameraPitch(SaturnClient.client.player.getPitch()); - cameraOverriddenEntity.freelook$setCameraYaw(SaturnClient.client.player.getYaw()); - firstTime = false; - } - this.setRotation(cameraOverriddenEntity.freelook$getCameraYaw(), - cameraOverriddenEntity.freelook$getCameraPitch()); - - } - if (!FreelookMod.isFreeLooking() && cameraEntity instanceof ClientPlayerEntity) { - firstTime = true; - } - } - -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java deleted file mode 100644 index a079e19..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/entity/EntityMixin.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.saturnclient.impl.features.mixins.entity; - -import org.saturnclient.impl.features.entity.CameraOverriddenEntity; -import org.saturnclient.mod.mods.FreelookMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; - -@Mixin(Entity.class) -public class EntityMixin implements CameraOverriddenEntity { - @Unique - private float cameraPitch; - - @Unique - private float cameraYaw; - - @Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true) - public void changeCameraLookDirection(double xDelta, double yDelta, CallbackInfo ci) { - // noinspection ConstantValue// IntelliJ is incorrect here, this code block is - // reachable - if (FreelookMod.isFreeLooking() && (Object) this instanceof ClientPlayerEntity) { - double pitchDelta = (yDelta * 0.15); - double yawDelta = (xDelta * 0.15); - - this.cameraPitch = MathHelper.clamp(this.cameraPitch + (float) pitchDelta, -90.0f, 90.0f); - this.cameraYaw += (float) yawDelta; - - ci.cancel(); - - } - } - - @Override - @Unique - public float freelook$getCameraPitch() { - return this.cameraPitch; - } - - @Override - @Unique - public float freelook$getCameraYaw() { - return this.cameraYaw; - } - - @Override - @Unique - public void freelook$setCameraPitch(float pitch) { - this.cameraPitch = pitch; - } - - @Override - @Unique - public void freelook$setCameraYaw(float yaw) { - this.cameraYaw = yaw; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java deleted file mode 100644 index 0a61479..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/BackgroundRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.fog.FogRenderer; - -import org.saturnclient.mod.mods.NoFogMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(FogRenderer.class) -public class BackgroundRendererMixin { - // fog - @ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true) - private static float modifyFogStart(float viewDistance) { - if (NoFogMod.isActive()) { - return viewDistance * 2.0f; - } - - return viewDistance; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java deleted file mode 100644 index c6d97f3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.GameRenderer; - -import org.saturnclient.mod.mods.ZoomMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -/** - * Overrides the game's field-of-view when {@link ZoomMod} is active. - * - * The old code checked both {@code Zoom.isZooming} and - * {@code Zoom.shouldZoom()} separately. The refactored - * {@link ZoomMod#shouldZoom()} already ORs both conditions - * ({@code enabled.value && isZooming}), so only one check is needed. - * - * No {@link org.saturnclient.common.module.ModProvider} is required - * here because zooming is a pure render-time override with no per-tick - * engine queries. - */ -@Mixin(GameRenderer.class) -public class GameRendererMixin { - - /** - * After the vanilla FOV has been computed, divide it by the zoom - * level to produce the narrowed field-of-view. - */ - @Inject(method = "getFov", at = @At("RETURN"), cancellable = true) - private void onGetFov(CallbackInfoReturnable cir) { - if (ZoomMod.shouldZoom()) { - float zoomedFov = cir.getReturnValue() / ZoomMod.getZoomLevel(); - cir.setReturnValue(zoomedFov); - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java deleted file mode 100644 index 66a3119..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LightmapTextureManagerMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -// Code approach adapted from Gamma Utils: https://github.com/Sjouwer/gamma-utils - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.LightmapTextureManager; - -import org.saturnclient.mod.mods.FullbrightMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * Overrides the lightmap's gamma computation when - * {@link FullbrightMod} is active, replacing the vanilla - * brightness with a user-configured value. - * - * The old import was {@code org.saturnclient.feature.features.Fullbright}; - * it is now {@link FullbrightMod}. The injection target and - * strategy are unchanged. - */ -@Mixin(LightmapTextureManager.class) -public class LightmapTextureManagerMixin { - - /** - * If fullbright is active, substitute the feature's brightness - * value for whatever vanilla calculated. - */ - @ModifyExpressionValue(method = "update", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)) - private float modifyGamma(float original) { - if (FullbrightMod.shouldOverrideBrightness()) { - return FullbrightMod.getBrightnessValue(); - } - return original; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java deleted file mode 100644 index c8cd2c2..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRenderStateMixin.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.state.LivingEntityRenderState; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -/** - * Implements {@link HealthRenderState} on - * {@link LivingEntityRenderState}, injecting health and entity-type - * storage into every living entity's render-state snapshot. - * - * Previously imported {@code NametagsInterface.EntityType}; the enum - * now lives in {@link EntityFeature.EntityType} which is the single - * canonical definition shared by the mixin layer and the feature layer. - * - * The stored values are written by - * {@link LivingEntityRendererMixin#saturn$captureHealth} each time a - * render state is extracted from a live entity, and read by - * {@link NametagsMixin} at render time. - */ -@Mixin(LivingEntityRenderState.class) -public class LivingEntityRenderStateMixin implements HealthRenderState { - - @Unique - private float saturn$health = 0f; - @Unique - private float saturn$maxHealth = 1f; - @Unique - private EntityFeature.EntityType saturn$entityType = EntityFeature.EntityType.OTHER; - - @Override - public float saturn$getHealth() { - return saturn$health; - } - - @Override - public float saturn$getMaxHealth() { - return saturn$maxHealth; - } - - @Override - public void saturn$setHealth(float health, float maxHealth) { - this.saturn$health = health; - this.saturn$maxHealth = maxHealth; - } - - @Override - public EntityFeature.EntityType saturn$getEntityType() { - return saturn$entityType; - } - - @Override - public void saturn$setEntityType(EntityFeature.EntityType type) { - saturn$entityType = type; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java deleted file mode 100644 index 5e9d6a2..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/LivingEntityRendererMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.passive.PassiveEntity; -import net.minecraft.entity.player.PlayerEntity; - -import org.saturnclient.common.feature.EntityFeature; -import org.saturnclient.impl.features.entity.HealthRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Captures each living entity's health and type into the render state - * during {@code updateRenderState}, so that nametag rendering can read - * them without touching the live entity again. - * - * Previously imported {@code NametagsInterface.EntityType}; now uses - * {@link EntityFeature.EntityType} — the canonical enum shared across - * the whole module system. - * - * The injection target and strategy are unchanged from the original. - */ -@Mixin(LivingEntityRenderer.class) -public abstract class LivingEntityRendererMixin { - - @Inject(method = "updateRenderState", at = @At("TAIL")) - private void saturn$captureHealth(T entity, S state, float tickDelta, CallbackInfo ci) { - if (!(state instanceof HealthRenderState hrs)) - return; - - hrs.saturn$setHealth(entity.getHealth(), entity.getMaxHealth()); - - // Classify entity type for the nametag feature's filtering logic - EntityFeature.EntityType type; - if (entity instanceof PlayerEntity) - type = EntityFeature.EntityType.PLAYER; - else if (entity instanceof HostileEntity) - type = EntityFeature.EntityType.HOSTILE; - else if (entity instanceof PassiveEntity) - type = EntityFeature.EntityType.PASSIVE; - else - type = EntityFeature.EntityType.OTHER; - - hrs.saturn$setEntityType(type); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java deleted file mode 100644 index f9d59c8..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.saturnclient.impl.features.mixins.render; - -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.client.render.RenderTickCounter; - -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.HudMod; -import org.saturnclient.mod.Mod; -import org.saturnclient.mod.ModLayout; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.screens.HudEditor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Drives per-frame rendering for all registered features. - * - * This mixin is intentionally kept thin: it creates a {@link RenderScope}, - * iterates the enabled feature list from {@link ModManager}, and - * dispatches either {@link HudMod#renderHud} (for HUD elements) or - * {@link Mod#render} (for world-overlay features like Crosshair). - * - * No feature-specific logic lives here — all decisions about what to - * draw are made inside each feature class. - * - * Changes from the original: - * - Package imports updated to the refactored feature names (no - * more {@code feature.features.*}). - * - The HUD-editor screen check still uses the existing - * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is - * unchanged infrastructure. - */ -@Mixin(InGameHud.class) -public class RenderMixin { - - @Inject(method = "renderChat", at = @At("TAIL")) - public void renderMods(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { - TextRenderer textRenderer = SaturnClient.client.textRenderer; - - // Skip rendering while the HUD editor is open so the editor - // can draw its own preview layout without double-drawing. - if (textRenderer == null) - return; - if (SaturnClient.client.currentScreen instanceof SaturnScreenFabric f - && f.screen instanceof HudEditor) - return; - - RenderScope scope = new RenderScopeImpl(context); - - for (Mod feature : ModManager.ENABLED_MODS) { - if (!feature.isEnabled()) - continue; - - if (feature instanceof HudMod hud) { - ModLayout dim = hud.getDimensions(); - - scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); - - if (dim.renderBackground) { - scope.drawRoundedRectangle(0, 0, dim.width, dim.height, - dim.radius.value, dim.bgColor.value); - } - - hud.renderHud(scope); - scope.getMatrixStack().pop(); - - } else { - // Non-HUD features (e.g. CrosshairFeature) use the plain render hook. - feature.render(scope); - } - } - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java deleted file mode 100644 index 0818d8b..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/mixins/world/TpsMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.saturnclient.impl.features.mixins.world; - -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket; - -import org.saturnclient.mod.mods.TpsMod; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Feeds world-time packets into {@link TpsMod}'s TPS estimator. - * - * This is the only place in the entire codebase that reads a network - * packet and passes data to a feature. The feature's - * {@link TpsMod#onTimePacket(long)} method handles all averaging - * logic; the mixin is intentionally reduced to a single forwarding call. - * - * The only change from the original is renaming the import from - * {@code feature.features.Tps} to {@link TpsMod}. - */ -@Mixin(ClientPlayNetworkHandler.class) -public class TpsMixin { - - @Inject(method = "onWorldTimeUpdate", at = @At("HEAD")) - private void onWorldTimeUpdate(WorldTimeUpdateS2CPacket packet, CallbackInfo ci) { - TpsMod.onTimePacket(packet.time()); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java deleted file mode 100644 index dca37ad..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/network/NetworkFeatureImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.saturnclient.impl.features.network; - -import org.saturnclient.common.feature.NetworkFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.PlayerListEntry; - -/** - * Fabric implementation of {@link NetworkFeature}. - * - * Connection presence is checked via the network handler. - * Ping is read from the player's {@link PlayerListEntry} which the - * server populates; returns {@code -1} when unavailable. - */ -public class NetworkFeatureImpl implements NetworkFeature { - - private final MinecraftClient mc; - - public NetworkFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasNetwork() { - return mc.getNetworkHandler() != null; - } - - @Override - public int getPing() { - if (mc.player == null || mc.getNetworkHandler() == null) - return -1; - - PlayerListEntry entry = mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()); - - return entry != null ? entry.getLatency() : -1; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java deleted file mode 100644 index a161cd6..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/player/PlayerFeatureImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -package org.saturnclient.impl.features.player; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import org.saturnclient.common.feature.PlayerFeature; -import org.saturnclient.common.ref.game.EffectRef; -import org.saturnclient.common.ref.game.ItemStackRef; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Fabric implementation of {@link PlayerFeature}. - * - * All access to {@link MinecraftClient} and {@link ClientPlayerEntity} - * is encapsulated here. Features only ever see the {@link PlayerFeature} - * interface; they never import Minecraft classes directly. - * - * Every method guards against a missing player and returns a safe - * default so features are free of null checks. - */ -public class PlayerFeatureImpl implements PlayerFeature { - - private final MinecraftClient mc; - - public PlayerFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Internal helper — never returns null - // --------------------------------------------------------------- - - /** Returns the local player, or {@code null} if one is not loaded. */ - private ClientPlayerEntity player() { - return mc.player; - } - - // --------------------------------------------------------------- - // Presence - // --------------------------------------------------------------- - - @Override - public boolean hasPlayer() { - return mc.player != null; - } - - // --------------------------------------------------------------- - // Position - // --------------------------------------------------------------- - - @Override - public int getX() { - return hasPlayer() ? (int) player().getX() : 0; - } - - @Override - public int getY() { - return hasPlayer() ? (int) player().getY() : 0; - } - - @Override - public int getZ() { - return hasPlayer() ? (int) player().getZ() : 0; - } - - // --------------------------------------------------------------- - // Input / movement - // --------------------------------------------------------------- - - @Override - public boolean isForwardPressed() { - return mc.options.forwardKey.isPressed(); - } - - @Override - public boolean isBackPressed() { - return mc.options.backKey.isPressed(); - } - - @Override - public boolean isLeftPressed() { - return mc.options.leftKey.isPressed(); - } - - @Override - public boolean isRightPressed() { - return mc.options.rightKey.isPressed(); - } - - @Override - public boolean isJumpPressed() { - return mc.options.jumpKey.isPressed(); - } - - @Override - public boolean isAttackPressed() { - return mc.options.attackKey.isPressed(); - } - - @Override - public boolean isUsePressed() { - return mc.options.useKey.isPressed(); - } - - @Override - public boolean isSneaking() { - return hasPlayer() && player().isSneaking(); - } - - @Override - public boolean isUsingItem() { - return hasPlayer() && player().isUsingItem(); - } - - @Override - public boolean hasHorizontalCollision() { - return hasPlayer() && player().horizontalCollision; - } - - @Override - public boolean isOnGround() { - return hasPlayer() && player().isOnGround(); - } - - @Override - public void setSprinting(boolean sprinting) { - if (hasPlayer()) - player().setSprinting(sprinting); - } - - // --------------------------------------------------------------- - // Velocity - // --------------------------------------------------------------- - - @Override - public Velocity getVelocity() { - if (!hasPlayer()) - return Velocity.ZERO; - var v = player().getVelocity(); - return new Velocity(v.x, v.y, v.z); - } - - // --------------------------------------------------------------- - // Stats - // --------------------------------------------------------------- - - @Override - public float getHealth() { - return hasPlayer() ? player().getHealth() : 0f; - } - - // --------------------------------------------------------------- - // Equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getMainHand() { - return wrap(hasPlayer() ? player().getMainHandStack() : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getHelmet() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.HEAD) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getChestplate() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.CHEST) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getLeggings() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.LEGS) : ItemStack.EMPTY); - } - - @Override - public ItemStackRef getBoots() { - return wrap(hasPlayer() ? player().getEquippedStack(EquipmentSlot.FEET) : ItemStack.EMPTY); - } - - // --------------------------------------------------------------- - // Dummy equipment - // --------------------------------------------------------------- - - @Override - public ItemStackRef getDummyMainHand() { - return wrap(new ItemStack(Items.DIAMOND_SWORD)); - } - - @Override - public ItemStackRef getDummyHelmet() { - return wrap(new ItemStack(Items.DIAMOND_HELMET)); - } - - @Override - public ItemStackRef getDummyChestplate() { - return wrap(new ItemStack(Items.DIAMOND_CHESTPLATE)); - } - - @Override - public ItemStackRef getDummyLeggings() { - return wrap(new ItemStack(Items.DIAMOND_LEGGINGS)); - } - - @Override - public ItemStackRef getDummyBoots() { - return wrap(new ItemStack(Items.DIAMOND_BOOTS)); - } - - // --------------------------------------------------------------- - // Status effects - // --------------------------------------------------------------- - - @Override - public List getActiveEffects() { - if (!hasPlayer()) - return Collections.emptyList(); - - var effects = player().getActiveStatusEffects().values(); - List result = new ArrayList<>(effects.size()); - for (StatusEffectInstance instance : effects) { - result.add((EffectRef) instance); - } - return result; - } - - @Override - public List getDummyEffects() { - return List.of( - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("speed")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("strength")).get(), 12000, 2), - (EffectRef) new StatusEffectInstance( - Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2)); - } - - // --------------------------------------------------------------- - // Helpers - // --------------------------------------------------------------- - - private static ItemStackRef wrap(ItemStack stack) { - return (ItemStackRef) (Object) stack; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java deleted file mode 100644 index adb958c..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/render/RenderFeatureImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.impl.features.render; - -import org.saturnclient.common.feature.RenderFeature; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.option.Perspective; - -/** - * Fabric implementation of {@link RenderFeature}. - * - * Window dimensions and FPS are read directly from - * {@link MinecraftClient}. Camera perspective control delegates to - * {@link net.minecraft.client.option.GameOptions}. - */ -public class RenderFeatureImpl implements RenderFeature { - - private final MinecraftClient mc; - - public RenderFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - // --------------------------------------------------------------- - // Window - // --------------------------------------------------------------- - - @Override - public int getScaledWindowWidth() { - return mc.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return mc.getWindow().getScaledHeight(); - } - - // --------------------------------------------------------------- - // Performance - // --------------------------------------------------------------- - - @Override - public int getFps() { - return mc.getCurrentFps(); - } - - // --------------------------------------------------------------- - // Camera perspective - // --------------------------------------------------------------- - - @Override - public boolean isFirstPerson() { - return mc.options.getPerspective() == Perspective.FIRST_PERSON; - } - - @Override - public void setFirstPerson() { - mc.options.setPerspective(Perspective.FIRST_PERSON); - } - - @Override - public void setThirdPersonBack() { - mc.options.setPerspective(Perspective.THIRD_PERSON_BACK); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java deleted file mode 100644 index 4847509..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/features/world/WorldFeatureImpl.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.saturnclient.impl.features.world; - -import org.saturnclient.common.feature.WorldFeature; - -import net.minecraft.client.MinecraftClient; - -/** - * Fabric implementation of {@link WorldFeature}. - * - * Reads the client world's time directly from {@link MinecraftClient}. - * Returns safe defaults when no world is loaded. - */ -public class WorldFeatureImpl implements WorldFeature { - - private final MinecraftClient mc; - - public WorldFeatureImpl(MinecraftClient mc) { - this.mc = mc; - } - - @Override - public boolean hasWorld() { - return mc.world != null; - } - - /** - * Returns the total world age in ticks, or {@code 0} when no world - * is loaded. Used by {@link TpsFeature#onTimePacket} (which is - * called from the mixin and stores its own copy) and by - * {@link DayCounterFeature} for the day count. - */ - @Override - public long getWorldAge() { - return hasWorld() ? mc.world.getTime() : 0L; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java deleted file mode 100644 index edfcdb9..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/IdentifierMixin.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.util.Identifier; - -@Mixin(Identifier.class) -public abstract class IdentifierMixin implements IdentifierRef { - @Shadow - public abstract String toString(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java deleted file mode 100644 index 9a69341..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/ItemStackMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.game.ItemStackRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.item.ItemStack; - -@Mixin(ItemStack.class) -public abstract class ItemStackMixin implements ItemStackRef { - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract int getMaxDamage(); - - @Shadow - public abstract int getDamage(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java deleted file mode 100644 index bf6bc27..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.impl.mixins; - -import java.io.File; -import java.io.InputStream; -import java.util.UUID; - -import org.jetbrains.annotations.Nullable; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.common.ref.render.WindowRef; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.screen.world.SelectWorldScreen; -import net.minecraft.client.option.GameOptions; -import net.minecraft.client.session.Session; -import net.minecraft.client.util.Window; -import net.minecraft.resource.ReloadableResourceManagerImpl; -import net.minecraft.util.Identifier; - -@Mixin(MinecraftClient.class) -public abstract class MinecraftClientMixin implements MinecraftClientRef { - @Shadow - public File runDirectory; - - @Shadow - private Window window; - - @Shadow - private ReloadableResourceManagerImpl resourceManager; - - @Shadow - public GameOptions options; - - @Shadow - private Session session; - - @Shadow - public abstract void setScreen(@Nullable Screen screen); - - @Shadow - @Override - public abstract void scheduleStop(); - - @Override - public File getRunDirectory() { - return runDirectory; - } - - @Override - public InputStream getResource(IdentifierRef identifier) { - try { - return resourceManager.getResource((Identifier) (Object) identifier).get().getInputStream(); - } catch (Exception e) { - return null; - } - } - - @Override - public WindowRef getWindow() { - return (WindowRef) (Object) this.window; - } - - @Override - public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); - } - - @Override - public void setScreen(MinecraftScreen screen) { - SaturnScreenFabric exitTarget = new SaturnScreenFabric(new TitleMenu()); - - switch (screen) { - case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); - break; - - case Multiplayer: - this.setScreen(new MultiplayerScreen(exitTarget)); - break; - - case Options: - this.setScreen(new OptionsScreen(exitTarget, this.options)); - break; - } - } - - @Override - public String getAccessToken() { - if (session == null) { - return null; - } - - return this.session.getAccessToken(); - } - - @Override - public UUID getUuid() { - if (session == null) { - return null; - } - return this.session.getUuidOrNull(); - } - - @Override - public String getUsername() { - if (session == null) { - return null; - } - return this.session.getUsername(); - } - - @Override - public void onClientStopping(Runnable handler) { - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> handler.run()); - } - - @Override - public void executeOnThread(Runnable runnable) { - ((java.util.concurrent.Executor) (Object) this).execute(runnable); - } - - @Override - @SuppressWarnings("resource") - public String getPlayerListEntry(UUID uuid) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(uuid); - if (entry == null) - return null; - - return entry.getProfile().name(); - } - - @Override - @SuppressWarnings("resource") - public UUID getPlayerListEntryUUID(String name) { - var client = (MinecraftClient) (Object) this; - var handler = client.getNetworkHandler(); - - if (handler == null) - return null; - - var entry = handler.getPlayerListEntry(name); - if (entry == null) - return null; - - return entry.getProfile().id(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java deleted file mode 100644 index 628e433..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/QuaternionfMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.joml.Quaternionf; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Quaternionf.class) -public abstract class QuaternionfMixin implements QuaternionfRef { -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java deleted file mode 100644 index 6cf07bc..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/SpriteMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.saturnclient.impl.mixins; - -import net.minecraft.client.texture.Sprite; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(Sprite.class) -public abstract class SpriteMixin implements SpriteRef { -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java deleted file mode 100644 index 122ba6c..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.EffectRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.gui.hud.InGameHud; -import net.minecraft.entity.effect.StatusEffect; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.Identifier; - -@Mixin(StatusEffectInstance.class) -public abstract class StatusEffectMixin implements EffectRef { - - @Shadow - public abstract boolean shouldShowIcon(); - - @Shadow - public abstract boolean isInfinite(); - - @Shadow - public abstract int getDuration(); - - @Shadow - public abstract RegistryEntry getEffectType(); - - @Override - public SpriteRef getIcon() { - return null; - } - - @Override - public IdentifierRef getIconId() { - Identifier id = InGameHud.getEffectTexture(getEffectType()); - - return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png"); - } - - @Override - public String getInfiniteText() { - return "∞"; - } - - @Override - public int getDurationSeconds() { - return getDuration() / 20; // ticks → seconds - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java deleted file mode 100644 index 9ed634f..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/TextMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.spongepowered.asm.mixin.Mixin; - -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.StyleSpriteSource.Font; -import net.minecraft.util.Identifier; - -@Mixin(Text.class) -public interface TextMixin extends TextRef { - - @Override - public default TextRef withFont(IdentifierRef font) { - return (TextRef) (((Text) this).copy().setStyle(Style.EMPTY.withFont(new Font((Identifier) (Object) font)))); - } - - @Override - public default int getWidth() { - return SaturnClient.client.textRenderer.getWidth((Text) this); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java deleted file mode 100644 index 5629068..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/mixins/WindowMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.impl.mixins; - -import org.saturnclient.common.ref.render.WindowRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import net.minecraft.client.util.Window; - -@Mixin(Window.class) -public abstract class WindowMixin implements WindowRef { - @Shadow - public abstract int getWidth(); - - @Shadow - public abstract int getHeight(); - - @Shadow - public abstract int getFramebufferWidth(); - - @Shadow - public abstract int getFramebufferHeight(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java deleted file mode 100644 index c424273..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/FeatureProviderFabric.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.saturnclient.impl.provider; - -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.common.feature.*; -import org.saturnclient.common.provider.FeatureProvider; -import org.saturnclient.impl.features.entity.EntityFeatureImpl; -import org.saturnclient.impl.features.network.NetworkFeatureImpl; -import org.saturnclient.impl.features.player.PlayerFeatureImpl; -import org.saturnclient.impl.features.render.RenderFeatureImpl; -import org.saturnclient.impl.features.world.WorldFeatureImpl; - -/** - * Fabric implementation of {@link FeatureProvider}. - * - * Instantiated once during client startup (e.g. in the mod initialiser) - * and passed to every feature constructor. All five sub-modules share - * the same {@link MinecraftClient} reference so there is no - * inconsistency between modules reading state within the same tick. - * - *
{@code
- * FeatureProvider provider = new FeatureProviderFabric(MinecraftClient.getInstance());
- * FeatureManager.register(new AutoSprintFeature(provider));
- * FeatureManager.register(new CoordinatesFeature(provider));
- * // …
- * }
- */ -public class FeatureProviderFabric implements FeatureProvider { - - private final PlayerFeature player; - private final WorldFeature world; - private final EntityFeature entity; - private final RenderFeature render; - private final NetworkFeature network; - - public FeatureProviderFabric(MinecraftClient mc) { - this.player = new PlayerFeatureImpl(mc); - this.world = new WorldFeatureImpl(mc); - this.entity = new EntityFeatureImpl(mc); - this.render = new RenderFeatureImpl(mc); - this.network = new NetworkFeatureImpl(mc); - } - - @Override - public PlayerFeature player() { - return player; - } - - @Override - public WorldFeature world() { - return world; - } - - @Override - public EntityFeature entity() { - return entity; - } - - @Override - public RenderFeature render() { - return render; - } - - @Override - public NetworkFeature network() { - return network; - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java deleted file mode 100644 index f8a896f..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.lwjgl.glfw.GLFW; -import org.saturnclient.common.provider.GLFWProvider; -import org.saturnclient.saturnclient.SaturnClient; - -public class GLFWProviderImpl implements GLFWProvider { - @Override - public boolean isKeyPressed(int key) { - return GLFW.glfwGetKey(SaturnClient.client.getWindow().getHandle(), key) == GLFW.GLFW_PRESS - && SaturnClient.client.currentScreen == null; - } - - @Override - public String getKeyName(int key) { - return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java deleted file mode 100644 index cf59bd7..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/RefConstructorImpl.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.saturnclient.impl.provider; - -import org.saturnclient.common.provider.RefConstructorProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.render.TextRef; - -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class RefConstructorImpl implements RefConstructorProvider { - @Override - public IdentifierRef identifier(String fullPath) { - return (IdentifierRef) (Object) Identifier.of(fullPath); - } - - @Override - public IdentifierRef identifier(String namespace, String path) { - return (IdentifierRef) (Object) Identifier.of(namespace, path); - } - - @Override - public TextRef text(String text) { - return (TextRef) Text.literal(text); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java deleted file mode 100644 index 87dd445..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.impl.provider; - -import java.awt.image.BufferedImage; -import java.util.UUID; - -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.Text; - -import org.saturnclient.common.provider.SaturnProvider; -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.game.MinecraftClientRef; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; -import org.saturnclient.saturnclient.SaturnClient; - -public class SaturnProviderImpl implements SaturnProvider { - @Override - public MinecraftClientRef getClient() { - return (MinecraftClientRef) SaturnClient.client; - } - - @Override - public void playEmote(UUID fromPlayerUuid, String emoteIdOrNull) { - if (fromPlayerUuid == null) { - return; - } - // An empty or unknown ID stops whatever the player is playing. - Emotes.get(emoteIdOrNull == null ? "" : emoteIdOrNull).ifPresentOrElse( - emote -> org.saturnclient.emotes.fabric.Emotes.play(fromPlayerUuid, emote.animation()), - () -> org.saturnclient.emotes.fabric.Emotes.stop(fromPlayerUuid)); - } - - @Override - public void logInfo(String message) { - SaturnClient.LOGGER.info(message); - } - - @Override - public void logError(String message) { - SaturnClient.LOGGER.error(message); - } - - @Override - public void logError(String message, Throwable throwable) { - SaturnClient.LOGGER.error(message, throwable); - } - - /** Shown longer than the vanilla default, since these ask the player to act. */ - private static final SystemToast.Type WARNING_TOAST = new SystemToast.Type(15_000L); - - @Override - public String getModVersion() { - return FabricLoader.getInstance().getModContainer(SaturnClient.MOD_ID) - .map(mod -> mod.getMetadata().getVersion().getFriendlyString()) - .orElse("unknown"); - } - - @Override - public void showWarning(String title, String message) { - MinecraftClient client = MinecraftClient.getInstance(); - client.execute(() -> client.getToastManager().add( - SystemToast.create(client, WARNING_TOAST, Text.literal(title), Text.literal(message)))); - } - - @Override - public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) { - IdentifierUtils.registerBufferedImageTextureFast(i, bi); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java deleted file mode 100644 index 62d92e3..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.saturnclient.impl.ref; - -import org.joml.Matrix3x2fStack; -import org.saturnclient.common.ref.render.MatrixStackRef; - -public class Matrix3x2fStackRef implements MatrixStackRef { - public final Matrix3x2fStack stack; - - public Matrix3x2fStackRef(Matrix3x2fStack stack) { - this.stack = stack; - } - - @Override - public void push() { - stack.pushMatrix(); - } - - @Override - public void pop() { - stack.popMatrix(); - } - - @Override - public void scale(float x, float y) { - stack.scale(x, y); - } - - @Override - public void translate(float x, float y) { - stack.translate(x, y); - } - - @Override - public void rotate(float angle) { - stack.rotate((float) Math.toRadians(angle)); - } - - @Override - public void rotate(float angle, float originX, float originY, float originZ) { - translate(originX, originY); - rotate(angle); - translate(-originX, -originY); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java deleted file mode 100644 index 3c58c85..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.saturnclient.impl.ui; - -import org.jetbrains.annotations.Nullable; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.ui.ElementContext; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.components.SkinPreview.EntityDrawer; - -import net.minecraft.client.render.entity.EntityRenderManager; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.LivingEntity; - -public class EntityDrawerImpl implements EntityDrawer { - @Override - public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { - LivingEntity entity = SaturnClient.client.player; - - if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, - SaturnClient.client.player); - } - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, - float mouseX, float mouseY, LivingEntity entity) { - float f = (float) (x1 + x2) / 2.0F; - float g = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(x1, y1, x2, y2); - float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); - float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); - Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); - quaternionf.mul(quaternionf2); - float j = entity.bodyYaw; - float k = entity.getYaw(); - float l = entity.getPitch(); - float m = entity.lastHeadYaw; - float n = entity.headYaw; - entity.bodyYaw = 180.0F + h * 20.0F; - entity.setYaw(180.0F + h * 40.0F); - entity.setPitch(-i * 20.0F); - entity.headYaw = entity.getYaw(); - entity.lastHeadYaw = entity.getYaw(); - float o = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); - float p = (float) size / o; - drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); - entity.bodyYaw = j; - entity.setYaw(k); - entity.setPitch(l); - entity.lastHeadYaw = m; - entity.headYaw = n; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, - Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, - LivingEntity entity) { - EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); - EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); - entityRenderState.hitbox = null; - - if (renderScope instanceof RenderScopeImpl i) - i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java deleted file mode 100644 index b613ad4..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ /dev/null @@ -1,347 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Objects; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3x2f; -import org.joml.Matrix3x2fStack; -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.mojang.blaze3d.textures.GpuTextureView; - -import org.saturnclient.common.ref.asset.IdentifierRef; -import org.saturnclient.common.ref.asset.SpriteRef; -import org.saturnclient.common.ref.game.ItemStackRef; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.impl.ref.Matrix3x2fStackRef; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Fonts; -import org.saturnclient.ui.resources.SvgTexture; - -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.ScreenRect; -import net.minecraft.client.gui.render.state.ColoredQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.GuiRenderState; -import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; -import net.minecraft.client.gui.render.state.TextGuiElementRenderState; -import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; -import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.client.render.item.KeyedItemRenderState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.TextureSetup; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemDisplayContext; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.crash.CrashException; -import net.minecraft.util.crash.CrashReport; -import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.world.World; - -public class RenderScopeImpl implements RenderScope { - - public final Matrix3x2fStackRef matrices; - public final GuiRenderState state; - - private ScissorStack scissorStack; - private int opacity = 0xFF << 24; - - public RenderScopeImpl(DrawContext context) { - this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); - } - - public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.matrices = new Matrix3x2fStackRef(matrices); - this.state = state; - this.scissorStack = new ScissorStack(); - } - - @Override - public MatrixStackRef getMatrixStack() { - return matrices; - } - - @Override - public void setOpacity(float alpha) { - this.opacity = ((int) (alpha * 255)) << 24; - } - - @Override - public int getColor(int color) { - int originalAlpha = (color >>> 24) & 0xFF; - int newAlpha = (opacity >>> 24) & 0xFF; - int mixedAlpha = (originalAlpha * newAlpha) / 255; - return (mixedAlpha << 24) | (color & 0x00FFFFFF); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int color) { - this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState( - RenderPipelines.GUI, - TextureSetup.empty(), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, color, color, - this.scissorStack.peekLast())); - } - - @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - if (x2 < x1) { - int tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - this.fill(x1, y1, x2, y2, color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) - scale *= 2; - - int lineIndex = 0; - for (String line : text.split("\n")) { - int finalColor = getColor(color); - - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); - - this.state.addText( - new TextGuiElementRenderState( - SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), - new Matrix3x2f(this.matrices.stack), - 0, font == 0 ? 1 : 8, - finalColor, 0, false, this.scissorStack.peekLast())); - - matrices.pop(); - - lineIndex++; - } - } - - @Override - public int getScaledWindowWidth() { - return SaturnClient.client.getWindow().getScaledWidth(); - } - - @Override - public int getScaledWindowHeight() { - return SaturnClient.client.getWindow().getScaledHeight(); - } - - // Texture rendering - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - drawTexture(sprite, x, y, u, v, width, height, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight) { - drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { - drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0f) / textureWidth, - (u + regionWidth) / textureWidth, - (v + 0f) / textureHeight, - (v + regionHeight) / textureHeight, - color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, - float u1, float u2, float v1, float v2, int color) { - if (color == 0) - return; - color = getColor(color); - - if (sprite.getPath().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg( - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI_TEXTURED, - TextureSetup.withoutGlTexture(gpuTextureView), - new Matrix3x2f(this.matrices.stack), - x1, y1, x2, y2, u1, u2, v1, v2, color, - this.scissorStack.peekLast())); - } - - // Scissor management - @Override - public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); - scissorStack.push(rect); - } - - @Override - public void disableScissor() { - scissorStack.pop(); - } - - @Override - public boolean scissorContains(int x, int y) { - return scissorStack.contains(x, y); - } - - public static class ScissorStack { - private final Deque stack = new ArrayDeque<>(); - - public ScreenRect push(ScreenRect rect) { - ScreenRect last = stack.peekLast(); - if (last != null) { - ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); - stack.addLast(intersection); - return intersection; - } else { - stack.addLast(rect); - return rect; - } - } - - @Nullable - public ScreenRect pop() { - if (stack.isEmpty()) - throw new IllegalStateException("Scissor stack underflow"); - stack.removeLast(); - return stack.peekLast(); - } - - @Nullable - public ScreenRect peekLast() { - return stack.peekLast(); - } - - public boolean contains(int x, int y) { - return stack.isEmpty() || stack.peekLast().contains(x, y); - } - } - - // Item rendering - @Override - public void drawItem(ItemStackRef stack, int x, int y) { - drawItem(null, SaturnClient.client.world, stack, x, y, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - KeyedItemRenderState keyedItemRenderState = new KeyedItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(keyedItemRenderState, stack, - ItemDisplayContext.GUI, world, - entity, seed); - - try { - this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), keyedItemRenderState, x, y, - this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); - } - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { - Sprite mcSprite = (Sprite) sprite; - if (color == 0 || width == 0 || height == 0) - return; - - drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, - mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); - } - - @Override - public void draw() { - // No-op for now - } - - public void drawBorder(int x, int y, int width, int height, int color) { - fill(x, y, x + width, y + 1, color); - fill(x, y + height - 1, x + width, y + height, color); - fill(x, y + 1, x + 1, y + height - 1, color); - fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } - - public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, - @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { - - Matrix3x2f mat = this.matrices.stack; - float offsetX = mat.m20; - float offsetY = mat.m21; - float scaleX = mat.m00; // current matrix X scale - float scaleY = mat.m11; // current matrix Y scale - - int adjustedX1 = (int) (x1 * scaleX + offsetX); - int adjustedY1 = (int) (y1 * scaleY + offsetY); - int adjustedX2 = (int) (x2 * scaleX + offsetX); - int adjustedY2 = (int) (y2 * scaleY + offsetY); - - float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too - - this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, - overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, - this.scissorStack.peekLast())); - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java deleted file mode 100644 index 91d5a74..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.saturnclient.impl.ui; - -import java.time.Duration; -import java.time.Instant; - -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.SaturnScreen; -import org.saturnclient.ui.SaturnScreen.ScreenProvider; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.Click; -import net.minecraft.client.gui.CubeMapRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.RotatingCubeMapRenderer; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.input.KeyInput; -import net.minecraft.client.texture.ResourceTexture; -import net.minecraft.client.texture.TextureManager; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - -public class SaturnScreenFabric extends Screen implements ScreenProvider { - protected static final Identifier PANORAMA = Identifier.of("saturnclient", - "textures/gui/title/background/panorama"); - protected static final CubeMapRenderer PANORAMA_RENDERER = new CubeMapRenderer(PANORAMA); - - public static final RotatingCubeMapRenderer ROTATING_PANORAMA_RENDERER; - - static { - ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); - } - - public final SaturnScreen screen; - - public static void preload(MinecraftClient client) { - TextureManager textureManager = client.getTextureManager(); - for (int i = 0; i < 6; i++) { - String var10001 = PANORAMA.getPath(); - Identifier tex = PANORAMA.withPath(var10001 + "_" + i + ".png"); - ResourceTexture resourceTexture = new ResourceTexture(tex); - textureManager.registerTexture(tex, resourceTexture); - } - } - - public SaturnScreenFabric(SaturnScreen screen) { - super(Text.literal(screen.title)); - screen.provider = this; - this.screen = screen; - } - - @Override - protected void init() { - screen.init(); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - if (screen.start == null) { - screen.start = Instant.now(); - } - long elapsed = Duration.between(screen.start, Instant.now()).toMillis(); - - mouseX *= 2; - mouseY *= 2; - - if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); - } - - RenderScope renderScope = new RenderScopeImpl(context); - - screen.render(renderScope, mouseX, mouseY, delta, elapsed); - } - - @Override - public boolean mouseClicked(Click click, boolean doubled) { - if (screen.mouseClicked(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseClicked(click, doubled); - } - - @Override - public boolean mouseDragged(Click click, double offsetX, double offsetY) { - if (screen.mouseDragged(click.x(), click.y(), click.button(), 0.0, 0.0)) { - return true; - } - - return super.mouseDragged(click, offsetX, offsetY); - } - - @Override - public boolean mouseReleased(Click click) { - if (screen.mouseReleased(click.x(), click.y(), click.button())) { - return true; - } - - return super.mouseReleased(click); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - if (screen.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)) { - return true; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } - - @Override - public boolean keyPressed(KeyInput input) { - if (screen.keyPressed(input.getKeycode(), input.scancode(), input.modifiers())) { - return true; - } - - return super.keyPressed(input); - } - - @Override - public void resize(MinecraftClient client, int width, int height) { - screen.resize(width, height); - super.resize(client, width, height); - } - - @Override - public void close() { - this.screen.onClose(); - super.close(); - } - - @Override - public int getWidth() { - return width * 2; - } - - @Override - public int getHeight() { - return height * 2; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java deleted file mode 100644 index c44e106..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.saturnclient.saturnclient; - -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.MinecraftClient; - -import org.saturnclient.client.ServiceClient; -import org.saturnclient.cosmetics.Emotes; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.impl.provider.GLFWProviderImpl; -import org.saturnclient.impl.provider.FeatureProviderFabric; -import org.saturnclient.impl.provider.RefConstructorImpl; -import org.saturnclient.impl.provider.SaturnProviderImpl; -import org.saturnclient.impl.ui.EntityDrawerImpl; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.mod.ModManager; -import org.saturnclient.saturnclient.event.KeyInputHandler; -import org.saturnclient.config.Config; -import org.saturnclient.config.ConfigManager; -import org.saturnclient.ui.components.SkinPreview; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Main class for the Saturn Client mod. - */ -public class SaturnClient implements ModInitializer { - - public static final String MOD_ID = "saturnclient"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static MinecraftClient client; - - @Override - public void onInitialize() { - LOGGER.info("Initializing " + MOD_ID); - client = MinecraftClient.getInstance(); - - Providers.saturn = new SaturnProviderImpl(); - Providers.refConstructor = new RefConstructorImpl(); - Providers.GLFW = new GLFWProviderImpl(); - Providers.feature = new FeatureProviderFabric(client); - SkinPreview.DRAWER = new EntityDrawerImpl(); - - Config.init(); - ModManager.init(); - - client.execute(() -> { - SaturnScreenFabric.preload(client); - }); - - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save()); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - for (org.saturnclient.mod.Mod m : ModManager.ENABLED_MODS) { - m.tick(); - } - }); - - KeyInputHandler.register(); - Emotes.initialize(); - ServiceClient.initialize(); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java deleted file mode 100644 index e34af31..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/SaturnRenderState.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.saturnclient.saturnclient; - -import org.saturnclient.client.player.SaturnPlayer; - -import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey; - -public class SaturnRenderState { - public static RenderStateDataKey saturnDataKey = RenderStateDataKey - .create(() -> "saturn-client-player"); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java deleted file mode 100644 index f8ba756..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.saturnclient.saturnclient.event; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import net.minecraft.util.Identifier; - -import org.saturnclient.config.Config; -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.common.provider.Providers; -import org.saturnclient.client.ServiceClient; -import org.saturnclient.emotes.fabric.Emotes; -import org.saturnclient.ui.screens.EmoteWheel; -import org.saturnclient.ui.screens.ShiftMenu; - -import org.lwjgl.glfw.GLFW; - -/** - * Handles keyboard input events for the Saturn Client. - * Manages keybindings and their associated actions. - */ -public class KeyInputHandler { - private static final Identifier KEY_CATEGORY = Identifier.of("saturnclient", "key.category.saturnclient"); - private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; - private static KeyBinding mainMenuKeyBinding; - - public static void register() { - mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding( - new KeyBinding( - MAIN_MENU_KEY_ID, - DEFAULT_MENU_KEY, - KeyBinding.Category.create(KEY_CATEGORY))); - - // Register the event handler for the main menu key - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (mainMenuKeyBinding.wasPressed()) { - Providers.saturn.getClient().setScreen(new ShiftMenu()); - } - - if (Config.openEmoteWheel.wasKeyPressed() && client.currentScreen == null - && !InputUtil.isKeyPressed(client.getWindow(), GLFW.GLFW_KEY_F3)) { - Providers.saturn.getClient().setScreen(new EmoteWheel()); - } - - // Sneaking cancels your own emote, for everyone. - if (SaturnClient.client.player != null && SaturnClient.client.player.isSneaking() - && Emotes.playing(SaturnClient.client.player.getUuid()).isPresent()) { - Emotes.stop(SaturnClient.client.player.getUuid()); - ServiceClient.emote(""); - } - }); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java deleted file mode 100644 index 9c2d8f0..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/DrawContextAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.render.state.GuiRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(DrawContext.class) -public interface DrawContextAccessor { - @Accessor("state") - GuiRenderState getState(); -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java deleted file mode 100644 index 6da5ccb..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/PlayerEntityRendererMixin.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.ClientPlayerLikeEntity; -import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.client.render.entity.PlayerEntityRenderer; -import net.minecraft.client.render.entity.model.PlayerEntityModel; -import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.PlayerLikeEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.saturnclient.impl.cosmetics.CloakFeatureRenderer; -import org.saturnclient.impl.cosmetics.HatFeatureRenderer; -import org.saturnclient.saturnclient.SaturnRenderState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(PlayerEntityRenderer.class) -public abstract class PlayerEntityRendererMixin - extends LivingEntityRenderer { - - protected PlayerEntityRendererMixin() { - super(null, null, 0.0f); - } - - @Inject(method = "", at = @At("TAIL")) - private void addCustomFeatureRenderer(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) { - this.addFeature(new HatFeatureRenderer(this)); - this.addFeature(new CloakFeatureRenderer(this, ctx.getEquipmentModelLoader())); - } - - @Inject(method = "updateRenderState", at = @At("TAIL")) - public void updateRenderState( - A entity, PlayerEntityRenderState state, - float f, CallbackInfo ci) { - if (entity == null) { - return; - } - - SaturnPlayer player = SaturnPlayer.get(entity.getUuid()); - - state.setData(SaturnRenderState.saturnDataKey, player); - - if (player != null) { - MutableText iconText = Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(player.uuid))); - - state.displayName = Text.empty() - .append(iconText.copy()) - .append(Text.empty().formatted(Formatting.RESET)) - .append(state.displayName.copy()); - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java deleted file mode 100644 index 061d641..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.config.Config; -import org.saturnclient.impl.ui.SaturnScreenFabric; -import org.saturnclient.ui.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(MinecraftClient.class) -public class SetScreenMixin { - @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) - private Screen replaceTitleScreen(Screen screen) { - if (Config.saturnTitleScreen.value) { - if (screen instanceof TitleScreen) - return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((MinecraftClient) (Object) this).world == null) - return new SaturnScreenFabric(new TitleMenu()); - } - - return screen; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java deleted file mode 100644 index cd463fd..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import java.util.Optional; -import java.util.function.Consumer; - -import org.saturnclient.config.Theme; -import org.saturnclient.impl.ui.RenderScopeImpl; -import org.saturnclient.ui.RenderScope; -import org.saturnclient.ui.resources.Textures; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Final; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.SplashOverlay; -import net.minecraft.resource.ResourceReload; -import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; - -@Mixin(SplashOverlay.class) -public abstract class SplashOverlayMixin { - - @Shadow - private MinecraftClient client; - @Shadow - private ResourceReload reload; - - @Shadow - private long reloadCompleteTime; - - @Shadow - private long reloadStartTime; - - @Shadow - @Final - private boolean reloading; - - @Shadow - @Final - private Consumer> exceptionHandler; - - @Shadow - private float progress; - - /** - * @author SaturnClient - * @reason Replace vanilla splash rendering completely but keep exit logic - */ - @Overwrite - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - int screenWidth = context.getScaledWindowWidth(); - int screenHeight = context.getScaledWindowHeight(); - long currentTime = Util.getMeasuringTimeMs(); - - // Initialize reload start time if not set - if (reloadStartTime == -1L) { - reloadStartTime = currentTime; - } - - // Compute fade-out progress after reload completes - float fadeOutProgress = reloadCompleteTime > -1L - ? (float) (currentTime - reloadCompleteTime) / 1000f - : -1f; - - int alpha = fadeOutProgress >= 0f - ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) - : 255; - - // Compute fade-in progress while reloading - float reloadProgress = reloadStartTime > -1L - ? (float) (currentTime - reloadStartTime) / 500f - : -1f; - - // Get render scope for better UI - RenderScope scope = new RenderScopeImpl(context); - - // Draw background overlay - if (fadeOutProgress >= 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(overlayAlpha, 0xFFFFFFFF)); - } else if (reloading) { - if (reloadProgress < 1.0F) { - renderCurrentScreen(context, mouseX, mouseY, delta); - } - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } else { - scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - float u = this.reload.getProgress(); - this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); - - // Draw central logo - drawLogo(scope, screenWidth, screenHeight, alpha); - renderProgressBar(scope, context, screenWidth, screenHeight, alpha); - - // Remove overlay after fade-out completes - if (fadeOutProgress >= 2.0F) { - client.setOverlay(null); - } - - // Handle reload completion and exceptions - handleReloadCompletion(context); - } - - private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { - if (client.currentScreen != null) { - client.currentScreen.render(context, mouseX, mouseY, delta); - } - } - - /** Draw the main logo centered */ - private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { - scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, - int alpha) { - int progressY = ((screenHeight - 5) / 2) + 25; - // context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, - // Theme.withAlpha(alpha, 0xFFFFFFFF)); - - int progressWidth = Math.min((int) (progress * 120), 120); - int progressX = (screenWidth - 120) / 2; - - context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, - Theme.withAlpha(alpha, 0xFFFFFFFF)); - } - - /** Compute overlay alpha from fade progress */ - private int computeOverlayAlpha(float progress) { - return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); - } - - /** Handle reload completion logic */ - private void handleReloadCompletion(DrawContext context) { - float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f - : -1f; - - if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { - try { - reload.throwException(); - exceptionHandler.accept(Optional.empty()); - } catch (Throwable ex) { - exceptionHandler.accept(Optional.of(ex)); - } - - reloadCompleteTime = Util.getMeasuringTimeMs(); - - if (client.currentScreen != null) { - client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); - } - } - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java deleted file mode 100644 index 4dd9311..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; - -import java.util.UUID; - -import org.saturnclient.client.player.Roles; -import org.saturnclient.client.player.SaturnPlayer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.mojang.authlib.GameProfile; - -@Mixin(PlayerListEntry.class) -public abstract class TabListMixin { - - /** - * Adds the Saturn Client icon to the player's name if they are online with - * Saturn Client, keeping any name, rank prefix or team formatting the server - * set. - */ - @Inject(method = "getDisplayName", at = @At("RETURN"), cancellable = true) - private void saturn$addSaturnIcon(CallbackInfoReturnable cir) { - PlayerListEntry entry = (PlayerListEntry) (Object) this; - GameProfile profile = entry.getProfile(); - String name = profile.name(); - UUID uuid = profile.id(); - - if (SaturnPlayer.get(name, uuid) == null) { - return; - } - - Text displayName = cir.getReturnValue(); - - // With no server-set name, vanilla shows the team-decorated profile name. - if (displayName == null) { - displayName = Team.decorateName(entry.getScoreboardTeam(), Text.literal(name)); - } - - cir.setReturnValue(Text.empty() - .append(Text.literal(Roles.getSaturnIndicator()) - .styled(style -> style.withColor(Roles.getIconColor(uuid)))) - .append(displayName)); - } -} diff --git a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java b/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java deleted file mode 100644 index 041e0cf..0000000 --- a/versions/1.21.9/src/main/java/org/saturnclient/saturnclient/mixin/WhoAmI.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -/* - * Original code from FokshaWasTaken (GitHub), - * Repository: https://github.com/FokshaWasTaken/who-am-i/ -*/ - -package org.saturnclient.saturnclient.mixin; - -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(LivingEntityRenderer.class) -public class WhoAmI { - @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getCameraEntity()Lnet/minecraft/entity/Entity;")) - public Entity obfuscateCameraEntity(Entity original) { - // hasLabel checks if the rendered entity is equal to the camera entity (aka our - // player), - // so by setting the camera entity to null in this instance makes the check - // always succeed - // this also allows to keep the other checks in mojang's code, such as checking - // if the hud is enabled etc. - return null; - } -} \ No newline at end of file diff --git a/versions/1.21.9/src/main/resources/fabric.mod.json b/versions/1.21.9/src/main/resources/fabric.mod.json deleted file mode 100644 index b5d0419..0000000 --- a/versions/1.21.9/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "schemaVersion": 1, - "id": "saturnclient", - "version": "${version}", - "name": "saturnclient", - "description": "The ultimate open source client", - "authors": ["Saturn", "ORUS"], - "contact": { - "website": "https://selimaj.dev", - "sources": "https://github.com/saturnclientmc/saturnclient" - }, - "license": "Apache-2.0", - "icon": "assets/saturnclient/icon.png", - "environment": "client", - "entrypoints": { - "main": ["org.saturnclient.saturnclient.SaturnClient"] - }, - "mixins": [ - "saturnclient.mixins.json", - "features.mixins.json", - "impl.mixins.json" - ], - "depends": { - "fabricloader": ">=${loader_version}", - "fabric": "*", - "minecraft": "${minecraft_version}" - } -} diff --git a/versions/1.21.9/src/main/resources/features.mixins.json b/versions/1.21.9/src/main/resources/features.mixins.json deleted file mode 100644 index 4c74195..0000000 --- a/versions/1.21.9/src/main/resources/features.mixins.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.features.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "render.GameRendererMixin", - "render.LightmapTextureManagerMixin", - "render.LivingEntityRendererMixin", - "render.LivingEntityRenderStateMixin", - "render.BackgroundRendererMixin", - "render.RenderMixin", - "world.TpsMixin", - "entity.CameraMixin", - "entity.EntityMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.9/src/main/resources/impl.mixins.json b/versions/1.21.9/src/main/resources/impl.mixins.json deleted file mode 100644 index ef9d58f..0000000 --- a/versions/1.21.9/src/main/resources/impl.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.impl.mixins", - "compatibilityLevel": "JAVA_21", - "client": [ - "IdentifierMixin", - "ItemStackMixin", - "MinecraftClientMixin", - "QuaternionfMixin", - "WindowMixin", - "TextMixin", - "SpriteMixin", - "StatusEffectMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/versions/1.21.9/src/main/resources/saturnclient.mixins.json b/versions/1.21.9/src/main/resources/saturnclient.mixins.json deleted file mode 100644 index d831845..0000000 --- a/versions/1.21.9/src/main/resources/saturnclient.mixins.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.saturnclient.saturnclient.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "TabListMixin", - "PlayerEntityRendererMixin", - "WhoAmI", - "DrawContextAccessor", - "SplashOverlayMixin", - "SetScreenMixin" - ], - "injectors": { - "defaultRequire": 1 - } -}