commit 28776fa5b6730e8968958056b3dffb045252f923 Author: arkonsadter Date: Fri Apr 24 14:54:59 2026 +0600 Initial commit diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..80b1307 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,10 @@ +{ + "permissions": { + "allow": [ + "Bash(curl -L -o gradle/wrapper/gradle-wrapper.jar https://raw.githubusercontent.com/gradle/gradle/master/gradle/wrapper/gradle-wrapper.jar)", + "Bash(git init *)", + "Bash(git checkout *)", + "Bash(git add *)" + ] + } +} diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..23db556 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,40 @@ +kind: pipeline +type: docker +name: build + +steps: + - name: build + image: eclipse-temurin:21-jdk + commands: + - chmod +x gradlew + - ./gradlew build --no-daemon + + - name: publish + image: eclipse-temurin:21-jdk + commands: + - mkdir -p artifacts + - cp build/libs/*.jar artifacts/ + when: + branch: + - main + + - name: upload-artifacts + image: plugins/s3 + settings: + bucket: cheat-builds + access_key: + from_secret: s3_access_key + secret_key: + from_secret: s3_secret_key + source: artifacts/*.jar + target: /builds/${DRONE_BUILD_NUMBER}/ + when: + branch: + - main + +trigger: + branch: + - main + event: + - push + - pull_request diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a5b016 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.gradle/ +build/ +out/ +*.iml +*.ipr +*.iws +.idea/ +run/ +logs/ +*.log +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a7e736d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Arkon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..870696c --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Cheat Client + +Advanced Minecraft 1.21.1 client mod built with Fabric. + +## Features + +- **Killaura** - Automatic attack with configurable range and crit-only mode +- **Triggerbot** - Auto-attack on crosshair target with crit-only mode +- **ESP** - See players through walls +- **Hitbox** - Expanded hitboxes for easier targeting +- **TargetHUD** - Display target information on screen + +## Building + +```bash +./gradlew build +``` + +The compiled mod will be in `build/libs/`. + +## Installation + +1. Install Fabric Loader for Minecraft 1.21.1 +2. Install Fabric API +3. Place the mod jar in your `.minecraft/mods` folder + +## CI/CD + +This project uses Drone CI for automated builds. Every push to main triggers a build and artifact upload. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..0a969c5 --- /dev/null +++ b/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'fabric-loom' version '1.7-SNAPSHOT' + id 'maven-publish' +} + +version = project.mod_version +group = project.maven_group + +base { + archivesName = project.archives_base_name +} + +repositories { + maven { url 'https://maven.fabricmc.net/' } +} + +dependencies { + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +} + +processResources { + inputs.property "version", project.version + filteringCharset "UTF-8" + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +def targetJavaVersion = 21 +tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = targetJavaVersion +} + +java { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} diff --git a/git.txt b/git.txt new file mode 100644 index 0000000..9f18af3 --- /dev/null +++ b/git.txt @@ -0,0 +1,6 @@ +git init +git checkout -b main +git add * +git commit -m "Initial commit" +git remote add origin https://git.nevetime.ru/Arkon/Cheat-1.21.11.git +git push -u origin main \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3f4dcb1 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,12 @@ +org.gradle.jvmargs=-Xmx2G +org.gradle.parallel=true + +minecraft_version=1.21.1 +yarn_mappings=1.21.1+build.3 +loader_version=0.16.5 + +mod_version=1.0.0 +maven_group=ru.nevetime +archives_base_name=cheat + +fabric_version=0.105.0+1.21.1 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..b1b8ef5 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a441313 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..7f119d2 --- /dev/null +++ b/gradlew @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +exec "$JAVACMD" $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6cc275d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,34 @@ +@rem Gradle startup script for Windows + +@if "%DEBUG%"=="" @echo off +setlocal enabledelayedexpansion + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +exit /b 1 + +:execute +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..027b233 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} diff --git a/src/main/java/ru/nevetime/cheat/CheatClient.java b/src/main/java/ru/nevetime/cheat/CheatClient.java new file mode 100644 index 0000000..f3a55c0 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/CheatClient.java @@ -0,0 +1,53 @@ +package ru.nevetime.cheat; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.nevetime.cheat.module.ModuleManager; +import ru.nevetime.cheat.module.combat.Killaura; +import ru.nevetime.cheat.module.combat.Triggerbot; +import ru.nevetime.cheat.module.render.ESP; +import ru.nevetime.cheat.module.render.Hitbox; +import ru.nevetime.cheat.module.render.TargetHUD; + +public class CheatClient implements ClientModInitializer { + public static final String MOD_ID = "cheat"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + + private static CheatClient INSTANCE; + private ModuleManager moduleManager; + + @Override + public void onInitializeClient() { + INSTANCE = this; + LOGGER.info("Initializing Cheat Client"); + + moduleManager = new ModuleManager(); + + moduleManager.register(new Killaura()); + moduleManager.register(new Triggerbot()); + moduleManager.register(new ESP()); + moduleManager.register(new Hitbox()); + moduleManager.register(new TargetHUD()); + + ClientTickEvents.END_CLIENT_TICK.register(client -> { + moduleManager.onTick(); + }); + + WorldRenderEvents.AFTER_ENTITIES.register(context -> { + moduleManager.onRender(context); + }); + + LOGGER.info("Cheat Client initialized"); + } + + public static CheatClient getInstance() { + return INSTANCE; + } + + public ModuleManager getModuleManager() { + return moduleManager; + } +} diff --git a/src/main/java/ru/nevetime/cheat/mixin/EntityMixin.java b/src/main/java/ru/nevetime/cheat/mixin/EntityMixin.java new file mode 100644 index 0000000..31e88a3 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/mixin/EntityMixin.java @@ -0,0 +1,23 @@ +package ru.nevetime.cheat.mixin; + +import net.minecraft.entity.Entity; +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 ru.nevetime.cheat.CheatClient; +import ru.nevetime.cheat.module.render.Hitbox; + +@Mixin(Entity.class) +public class EntityMixin { + @Inject(method = "getTargetingMargin", at = @At("RETURN"), cancellable = true) + private void onGetTargetingMargin(CallbackInfoReturnable cir) { + Hitbox hitbox = (Hitbox) CheatClient.getInstance() + .getModuleManager() + .getModule("Hitbox"); + + if (hitbox != null && hitbox.isEnabled()) { + cir.setReturnValue(cir.getReturnValue() + hitbox.getExpandAmount()); + } + } +} diff --git a/src/main/java/ru/nevetime/cheat/mixin/InGameHudMixin.java b/src/main/java/ru/nevetime/cheat/mixin/InGameHudMixin.java new file mode 100644 index 0000000..fcfcb34 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/mixin/InGameHudMixin.java @@ -0,0 +1,29 @@ +package ru.nevetime.cheat.mixin; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.render.RenderTickCounter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import ru.nevetime.cheat.CheatClient; +import ru.nevetime.cheat.module.render.TargetHUD; + +@Mixin(InGameHud.class) +public class InGameHudMixin { + @Inject(method = "render", at = @At("TAIL")) + private void onRender(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { + MinecraftClient mc = MinecraftClient.getInstance(); + if (mc.player == null) return; + + TargetHUD targetHUD = (TargetHUD) CheatClient.getInstance() + .getModuleManager() + .getModule("TargetHUD"); + + if (targetHUD != null) { + targetHUD.render(context, mc.getWindow().getScaledWidth(), mc.getWindow().getScaledHeight()); + } + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/Module.java b/src/main/java/ru/nevetime/cheat/module/Module.java new file mode 100644 index 0000000..83b63af --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/Module.java @@ -0,0 +1,60 @@ +package ru.nevetime.cheat.module; + +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.MinecraftClient; + +public abstract class Module { + protected final String name; + protected final Category category; + protected boolean enabled; + protected final MinecraftClient mc; + + public Module(String name, Category category) { + this.name = name; + this.category = category; + this.enabled = false; + this.mc = MinecraftClient.getInstance(); + } + + public void toggle() { + enabled = !enabled; + if (enabled) { + onEnable(); + } else { + onDisable(); + } + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + if (enabled) { + onEnable(); + } else { + onDisable(); + } + } + + public void onEnable() {} + public void onDisable() {} + public void onTick() {} + public void onRender(WorldRenderContext context) {} + + public String getName() { + return name; + } + + public Category getCategory() { + return category; + } + + public boolean isEnabled() { + return enabled; + } + + public enum Category { + COMBAT, + RENDER, + MOVEMENT, + MISC + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/ModuleManager.java b/src/main/java/ru/nevetime/cheat/module/ModuleManager.java new file mode 100644 index 0000000..c24c8c4 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/ModuleManager.java @@ -0,0 +1,41 @@ +package ru.nevetime.cheat.module; + +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import java.util.ArrayList; +import java.util.List; + +public class ModuleManager { + private final List modules = new ArrayList<>(); + + public void register(Module module) { + modules.add(module); + module.setEnabled(true); + } + + public void onTick() { + for (Module module : modules) { + if (module.isEnabled()) { + module.onTick(); + } + } + } + + public void onRender(WorldRenderContext context) { + for (Module module : modules) { + if (module.isEnabled()) { + module.onRender(context); + } + } + } + + public List getModules() { + return modules; + } + + public Module getModule(String name) { + return modules.stream() + .filter(m -> m.getName().equalsIgnoreCase(name)) + .findFirst() + .orElse(null); + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/combat/Killaura.java b/src/main/java/ru/nevetime/cheat/module/combat/Killaura.java new file mode 100644 index 0000000..5354b82 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/combat/Killaura.java @@ -0,0 +1,81 @@ +package ru.nevetime.cheat.module.combat; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Hand; +import ru.nevetime.cheat.module.Module; + +public class Killaura extends Module { + private double range = 4.0; + private boolean critsOnly = true; + private int attackDelay = 0; + + public Killaura() { + super("Killaura", Category.COMBAT); + } + + @Override + public void onTick() { + if (mc.player == null || mc.world == null) return; + + if (attackDelay > 0) { + attackDelay--; + return; + } + + Entity target = findTarget(); + if (target == null) return; + + if (critsOnly && !canCrit()) return; + + mc.interactionManager.attackEntity(mc.player, target); + mc.player.swingHand(Hand.MAIN_HAND); + attackDelay = 10; + } + + private Entity findTarget() { + Entity closest = null; + double closestDistance = range; + + for (Entity entity : mc.world.getEntities()) { + if (entity == mc.player) continue; + if (!(entity instanceof LivingEntity)) continue; + if (entity instanceof PlayerEntity && ((PlayerEntity) entity).isCreative()) continue; + if (!entity.isAlive()) continue; + + double distance = mc.player.distanceTo(entity); + if (distance < closestDistance) { + closest = entity; + closestDistance = distance; + } + } + + return closest; + } + + private boolean canCrit() { + return mc.player.fallDistance > 0.0F + && !mc.player.isOnGround() + && !mc.player.isClimbing() + && !mc.player.isTouchingWater() + && !mc.player.hasVehicle() + && mc.player.getVelocity().y < 0; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRange() { + return range; + } + + public void setCritsOnly(boolean critsOnly) { + this.critsOnly = critsOnly; + } + + public boolean isCritsOnly() { + return critsOnly; + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/combat/Triggerbot.java b/src/main/java/ru/nevetime/cheat/module/combat/Triggerbot.java new file mode 100644 index 0000000..95a5a51 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/combat/Triggerbot.java @@ -0,0 +1,59 @@ +package ru.nevetime.cheat.module.combat; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import ru.nevetime.cheat.module.Module; + +public class Triggerbot extends Module { + private boolean critsOnly = true; + private int attackDelay = 0; + + public Triggerbot() { + super("Triggerbot", Category.COMBAT); + } + + @Override + public void onTick() { + if (mc.player == null || mc.world == null) return; + + if (attackDelay > 0) { + attackDelay--; + return; + } + + HitResult hitResult = mc.crosshairTarget; + if (hitResult == null || hitResult.getType() != HitResult.Type.ENTITY) return; + + EntityHitResult entityHit = (EntityHitResult) hitResult; + Entity target = entityHit.getEntity(); + + if (!(target instanceof LivingEntity)) return; + if (!target.isAlive()) return; + + if (critsOnly && !canCrit()) return; + + mc.interactionManager.attackEntity(mc.player, target); + mc.player.swingHand(Hand.MAIN_HAND); + attackDelay = 10; + } + + private boolean canCrit() { + return mc.player.fallDistance > 0.0F + && !mc.player.isOnGround() + && !mc.player.isClimbing() + && !mc.player.isTouchingWater() + && !mc.player.hasVehicle() + && mc.player.getVelocity().y < 0; + } + + public void setCritsOnly(boolean critsOnly) { + this.critsOnly = critsOnly; + } + + public boolean isCritsOnly() { + return critsOnly; + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/render/ESP.java b/src/main/java/ru/nevetime/cheat/module/render/ESP.java new file mode 100644 index 0000000..d1a3626 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/render/ESP.java @@ -0,0 +1,100 @@ +package ru.nevetime.cheat.module.render; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.render.*; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; +import org.joml.Matrix4f; +import ru.nevetime.cheat.module.Module; + +public class ESP extends Module { + public ESP() { + super("ESP", Category.RENDER); + } + + @Override + public void onRender(WorldRenderContext context) { + if (mc.player == null || mc.world == null) return; + + MatrixStack matrices = context.matrixStack(); + matrices.push(); + + Vec3d camera = context.camera().getPos(); + matrices.translate(-camera.x, -camera.y, -camera.z); + + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.disableDepthTest(); + RenderSystem.setShader(GameRenderer::getPositionColorProgram); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR); + + for (Entity entity : mc.world.getEntities()) { + if (entity == mc.player) continue; + if (!(entity instanceof PlayerEntity)) continue; + if (!entity.isAlive()) continue; + + Box box = entity.getBoundingBox(); + drawBox(matrices, buffer, box, 1.0f, 0.0f, 0.0f, 1.0f); + } + + BufferRenderer.drawWithGlobalProgram(buffer.end()); + + RenderSystem.enableDepthTest(); + RenderSystem.disableBlend(); + + matrices.pop(); + } + + private void drawBox(MatrixStack matrices, BufferBuilder buffer, Box box, float r, float g, float b, float a) { + Matrix4f matrix = matrices.peek().getPositionMatrix(); + + float minX = (float) box.minX; + float minY = (float) box.minY; + float minZ = (float) box.minZ; + float maxX = (float) box.maxX; + float maxY = (float) box.maxY; + float maxZ = (float) box.maxZ; + + buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a); + + buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a); + + buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, minX, minY, minZ).color(r, g, b, a); + buffer.vertex(matrix, minX, maxY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, minY, minZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, maxY, minZ).color(r, g, b, a); + + buffer.vertex(matrix, maxX, minY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, a); + + buffer.vertex(matrix, minX, minY, maxZ).color(r, g, b, a); + buffer.vertex(matrix, minX, maxY, maxZ).color(r, g, b, a); + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/render/Hitbox.java b/src/main/java/ru/nevetime/cheat/module/render/Hitbox.java new file mode 100644 index 0000000..65a6695 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/render/Hitbox.java @@ -0,0 +1,19 @@ +package ru.nevetime.cheat.module.render; + +import ru.nevetime.cheat.module.Module; + +public class Hitbox extends Module { + private float expandAmount = 0.3f; + + public Hitbox() { + super("Hitbox", Category.RENDER); + } + + public float getExpandAmount() { + return expandAmount; + } + + public void setExpandAmount(float expandAmount) { + this.expandAmount = expandAmount; + } +} diff --git a/src/main/java/ru/nevetime/cheat/module/render/TargetHUD.java b/src/main/java/ru/nevetime/cheat/module/render/TargetHUD.java new file mode 100644 index 0000000..081f362 --- /dev/null +++ b/src/main/java/ru/nevetime/cheat/module/render/TargetHUD.java @@ -0,0 +1,72 @@ +package ru.nevetime.cheat.module.render; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import ru.nevetime.cheat.module.Module; + +public class TargetHUD extends Module { + private Entity currentTarget; + + public TargetHUD() { + super("TargetHUD", Category.RENDER); + } + + @Override + public void onTick() { + if (mc.player == null || mc.world == null) { + currentTarget = null; + return; + } + + currentTarget = findTarget(); + } + + private Entity findTarget() { + Entity closest = null; + double closestDistance = 20.0; + + for (Entity entity : mc.world.getEntities()) { + if (entity == mc.player) continue; + if (!(entity instanceof LivingEntity)) continue; + if (!entity.isAlive()) continue; + + double distance = mc.player.distanceTo(entity); + if (distance < closestDistance) { + closest = entity; + closestDistance = distance; + } + } + + return closest; + } + + public void render(DrawContext context, int screenWidth, int screenHeight) { + if (!isEnabled() || currentTarget == null) return; + if (!(currentTarget instanceof LivingEntity living)) return; + + int x = 10; + int y = 10; + + String name = currentTarget.getName().getString(); + float health = living.getHealth(); + float maxHealth = living.getMaxHealth(); + float distance = mc.player.distanceTo(currentTarget); + + context.fill(x, y, x + 150, y + 50, 0x80000000); + + context.drawText(mc.textRenderer, name, x + 5, y + 5, 0xFFFFFF, true); + context.drawText(mc.textRenderer, String.format("HP: %.1f/%.1f", health, maxHealth), x + 5, y + 20, 0xFF0000, true); + context.drawText(mc.textRenderer, String.format("Distance: %.1f", distance), x + 5, y + 35, 0xFFFFFF, true); + + int barWidth = 140; + int healthBarWidth = (int) ((health / maxHealth) * barWidth); + context.fill(x + 5, y + 48, x + 5 + barWidth, y + 52, 0xFF333333); + context.fill(x + 5, y + 48, x + 5 + healthBarWidth, y + 52, 0xFF00FF00); + } + + public Entity getCurrentTarget() { + return currentTarget; + } +} diff --git a/src/main/resources/assets/cheat/icon.png b/src/main/resources/assets/cheat/icon.png new file mode 100644 index 0000000..b066924 Binary files /dev/null and b/src/main/resources/assets/cheat/icon.png differ diff --git a/src/main/resources/cheat.mixins.json b/src/main/resources/cheat.mixins.json new file mode 100644 index 0000000..a0e437d --- /dev/null +++ b/src/main/resources/cheat.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "ru.nevetime.cheat.mixin", + "compatibilityLevel": "JAVA_21", + "client": [ + "InGameHudMixin", + "EntityMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..92b42ed --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,26 @@ +{ + "schemaVersion": 1, + "id": "cheat", + "version": "${version}", + "name": "Cheat", + "description": "Advanced client mod", + "authors": ["Arkon"], + "contact": {}, + "license": "MIT", + "icon": "assets/cheat/icon.png", + "environment": "client", + "entrypoints": { + "client": [ + "ru.nevetime.cheat.CheatClient" + ] + }, + "mixins": [ + "cheat.mixins.json" + ], + "depends": { + "fabricloader": ">=0.16.0", + "minecraft": "~1.21.1", + "java": ">=21", + "fabric-api": "*" + } +}