From 5ee6848f3054e850fc34793ef589de19f6f5200d Mon Sep 17 00:00:00 2001 From: Izuna Date: Sun, 16 Feb 2025 07:35:22 +0100 Subject: [PATCH 1/3] testing tensorflow as Smooth Mode --- build.gradle | 5 + .../minecraft/client/MixinKeyboardInput.java | 2 +- .../minecraft/entity/MixinLivingEntity.java | 6 +- .../minecraft/entity/MixinPlayerEntity.java | 2 +- .../mixins/minecraft/render/MixinCamera.java | 2 +- src/main/kotlin/Train.kt | 173 ++++++++++++++++++ .../module/modules/combat/ModuleAimbot.kt | 15 +- .../aimbot/autobow/AutoBowAutoShootFeature.kt | 2 +- .../place/SubmoduleCrystalPlacer.kt | 6 +- .../modules/combat/killaura/ModuleKillAura.kt | 4 +- .../debugrecorder/modes/AimDebugRecorder.kt | 90 ++++----- .../module/modules/movement/ModuleSprint.kt | 2 +- .../render/trajectories/ModuleTrajectories.kt | 2 +- .../utils/aiming/RotationManager.kt | 44 ++--- .../utils/aiming/RotationTarget.kt | 20 +- .../utils/aiming/RotationsConfigurable.kt | 14 +- .../{VecRotation.kt => RotationWithVector.kt} | 2 +- .../utils/aiming/features/FailFocus.kt | 94 ---------- .../utils/aiming/features/ShortStop.kt | 2 +- .../utils/aiming/features/UpRamp.kt | 65 ------- .../anglesmooth/AccelerationSmoothMode.kt | 1 - .../features/anglesmooth/AngleSmoothMode.kt | 1 - .../anglesmooth/BezierAngleSmoothMode.kt | 80 -------- .../ConditionalLinearAngleSmoothMode.kt | 5 +- .../anglesmooth/LinearAngleSmoothMode.kt | 5 +- .../anglesmooth/SigmoidAngleSmoothMode.kt | 97 ---------- .../anglesmooth/TestAngleSmoothMode.kt | 94 ++++++++++ .../utils/aiming/utils/RotationFinding.kt | 36 ++-- 28 files changed, 368 insertions(+), 503 deletions(-) create mode 100644 src/main/kotlin/Train.kt rename src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/{VecRotation.kt => RotationWithVector.kt} (92%) delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/FailFocus.kt delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/UpRamp.kt delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt delete mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt diff --git a/build.gradle b/build.gradle index 16735ca9132..ce9673a744d 100644 --- a/build.gradle +++ b/build.gradle @@ -160,6 +160,11 @@ dependencies { // includeDependency "org.graalvm.polyglot:ruby-community:24.0.2" // includeDependency "org.graalvm.polyglot:llvm-native-community:24.0.2" + // Kotlin DL + implementation 'org.jetbrains.kotlinx:kotlin-deeplearning-tensorflow:0.5.2' + implementation 'org.jetbrains.kotlinx:kotlin-deeplearning-dataset:0.5.2' + implementation 'org.tensorflow:libtensorflow:1.15.0' + // HTTP library includeDependency ("com.squareup.okhttp3:okhttp:5.0.0-alpha.14") { exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib" diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyboardInput.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyboardInput.java index 37156a2ee43..9a325af0573 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyboardInput.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/client/MixinKeyboardInput.java @@ -109,7 +109,7 @@ private PlayerInput modifyInput(PlayerInput original) { private DirectionalInput transformDirection(DirectionalInput input) { var player = MinecraftClient.getInstance().player; var rotation = RotationManager.INSTANCE.getCurrentRotation(); - var configurable = RotationManager.INSTANCE.getWorkingRotationTarget(); + var configurable = RotationManager.INSTANCE.getActiveRotationTarget(); float z = KeyboardInput.getMovementMultiplier(input.getForwards(), input.getBackwards()); float x = KeyboardInput.getMovementMultiplier(input.getLeft(), input.getRight()); diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinLivingEntity.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinLivingEntity.java index 0e8aa03f177..7e0d948418d 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinLivingEntity.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinLivingEntity.java @@ -171,7 +171,7 @@ private void hookAfterJumpEvent(CallbackInfo ci) { private Vec3d hookFixRotation(Vec3d original) { var rotationManager = RotationManager.INSTANCE; var rotation = rotationManager.getCurrentRotation(); - var configurable = rotationManager.getWorkingRotationTarget(); + var configurable = rotationManager.getActiveRotationTarget(); if ((Object) this != MinecraftClient.getInstance().player) { return original; @@ -247,7 +247,7 @@ private float hookModifyFallFlyingPitch(float original) { var rotationManager = RotationManager.INSTANCE; var rotation = rotationManager.getCurrentRotation(); - var configurable = rotationManager.getWorkingRotationTarget(); + var configurable = rotationManager.getActiveRotationTarget(); if (rotation == null || configurable == null || configurable.getMovementCorrection() == MovementCorrection.OFF) { return original; @@ -267,7 +267,7 @@ private Vec3d hookModifyFallFlyingRotationVector(Vec3d original) { var rotationManager = RotationManager.INSTANCE; var rotation = rotationManager.getCurrentRotation(); - var configurable = rotationManager.getWorkingRotationTarget(); + var configurable = rotationManager.getActiveRotationTarget(); if (rotation == null || configurable == null || configurable.getMovementCorrection() == MovementCorrection.OFF) { return original; diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinPlayerEntity.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinPlayerEntity.java index 9d97babb914..d0073e95872 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinPlayerEntity.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/entity/MixinPlayerEntity.java @@ -95,7 +95,7 @@ private float hookFixRotation(float original) { RotationManager rotationManager = RotationManager.INSTANCE; Rotation rotation = rotationManager.getCurrentRotation(); - RotationTarget configurable = rotationManager.getWorkingRotationTarget(); + RotationTarget configurable = rotationManager.getActiveRotationTarget(); if (configurable == null || configurable.getMovementCorrection() == MovementCorrection.OFF || rotation == null) { return original; diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinCamera.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinCamera.java index bfa00bdd872..44bb7073caa 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinCamera.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinCamera.java @@ -102,7 +102,7 @@ private void modifyCameraOrientation(BlockView area, Entity focusedEntity, boole this.setRotation(screen.getCameraRotation().x, screen.getCameraRotation().y); } - RotationTarget rotationTarget = RotationManager.INSTANCE.getWorkingRotationTarget(); + RotationTarget rotationTarget = RotationManager.INSTANCE.getActiveRotationTarget(); var previousRotation = RotationManager.INSTANCE.getPreviousRotation(); var currentRotation = RotationManager.INSTANCE.getCurrentRotation(); diff --git a/src/main/kotlin/Train.kt b/src/main/kotlin/Train.kt new file mode 100644 index 00000000000..6e55b76fd31 --- /dev/null +++ b/src/main/kotlin/Train.kt @@ -0,0 +1,173 @@ +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import net.ccbluex.liquidbounce.utils.aiming.data.Rotation +import net.ccbluex.liquidbounce.utils.kotlin.random +import org.jetbrains.kotlinx.dl.api.core.SavingFormat +import org.jetbrains.kotlinx.dl.api.core.Sequential +import org.jetbrains.kotlinx.dl.api.core.WritingMode +import org.jetbrains.kotlinx.dl.api.core.activation.Activations +import org.jetbrains.kotlinx.dl.api.core.initializer.HeNormal +import org.jetbrains.kotlinx.dl.api.core.layer.core.Dense +import org.jetbrains.kotlinx.dl.api.core.layer.core.Input +import org.jetbrains.kotlinx.dl.api.core.loss.Losses +import org.jetbrains.kotlinx.dl.api.core.metric.Metrics +import org.jetbrains.kotlinx.dl.api.core.optimizer.Adam +import org.jetbrains.kotlinx.dl.dataset.OnHeapDataset +import java.io.File +import kotlin.math.abs + +data class Vector(val x: Double, val y: Double, val z: Double) +data class Vec2f(val x: Float, val y: Float) +data class TrainingData( + val c_vector: Vector, + val w_vector: Vector, + val delta: Vec2f, + val distance: Double +) + +fun main() { + val linearTrainingData = generateTrainingData() + println("Generated ${linearTrainingData.size} training samples") + val trainingData = readTrainingDataFromFolder("./LiquidBounce/debug-recorder/Aim") + println("Read ${trainingData.size} training samples") + + val dataset = prepareData(linearTrainingData + trainingData) + val modelYaw = createAndTrainModel(dataset.features, dataset.labelX) + val modelPitch = createAndTrainModel(dataset.features, dataset.labelY) + + // Save the models + saveModel(modelYaw, "yaw_model") + saveModel(modelPitch, "pitch_model") + + println("Models trained and saved successfully.") +} + +const val SAMPLES = 100 + +/** + * Linear train data generator + */ +fun generateTrainingData(): List { + val trainingData = mutableListOf() + + repeat(SAMPLES) { + val targetYaw = (-180..180).random() + val targetPitch = (-5..10).random() + + val distance = (0f..4f).random() + println("Generating training data for distance $distance, yaw $targetYaw, pitch $targetPitch") + + val targetRotation = Rotation(targetYaw.toFloat(), targetPitch.toFloat()) + + val clientYaw = (-180..180).random() + val clientPitch = (-80..80).random() + var clientRotation = Rotation(clientYaw.toFloat(), clientPitch.toFloat()) + + while (clientRotation.angleTo(targetRotation) > 1.0E-5f) { + val diff = clientRotation.rotationDeltaTo(targetRotation) + val rotationDifference = diff.length() + val factorH = (40f..60f).random() + val straightLineYaw = (abs(diff.deltaYaw / rotationDifference) * factorH).toFloat() + val factorV = (40f..60f).random() + val straightLinePitch = (abs(diff.deltaPitch / rotationDifference) * factorV).toFloat() + + val nextClientRotation = Rotation( + clientRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), + clientRotation.pitch + diff.deltaPitch.coerceIn(-straightLinePitch, straightLinePitch) + ) + val diff2 = clientRotation.rotationDeltaTo(nextClientRotation) + + trainingData += TrainingData( + Vector(clientRotation.directionVector.x, clientRotation.directionVector.y, clientRotation.directionVector.z), + Vector(targetRotation.directionVector.x, targetRotation.directionVector.y, targetRotation.directionVector.z), + Vec2f(diff2.deltaYaw, diff2.deltaPitch), + distance + ) + + clientRotation = nextClientRotation + } + } + + println("Generated ${trainingData.size} training samples") + + return trainingData +} + +fun saveModel(model: Sequential, modelName: String) { + val savePath = File("./models/$modelName") + savePath.mkdirs() + model.save( + modelDirectory = savePath, + savingFormat = SavingFormat.TF_GRAPH_CUSTOM_VARIABLES, + saveOptimizerState = true, + writingMode = WritingMode.OVERRIDE + ) + println("Model saved to ${savePath.absolutePath}") +} + + +fun parseJson(jsonString: String): List { + val gson = Gson() + val listType = object : TypeToken>() {}.type + return gson.fromJson(jsonString, listType) +} + +fun readTrainingDataFromFolder(folderPath: String): List { + val folder = File(folderPath) + if (!folder.exists() || !folder.isDirectory) { + throw IllegalArgumentException("Invalid folder path: $folderPath") + } + + return folder.listFiles { file -> file.isFile && file.extension == "json" } + ?.flatMap { file -> + try { + parseJson(file.readText()) + } catch (e: Exception) { + println("Error parsing file ${file.name}: ${e.message}") + emptyList() + } + } ?: emptyList() +} + +data class Dataset(val features: Array, val labelX: FloatArray, val labelY: FloatArray) + +fun prepareData(trainingData: List): Dataset { + val features = trainingData.map { data -> + floatArrayOf( + data.c_vector.x.toFloat(), data.c_vector.y.toFloat(), data.c_vector.z.toFloat(), + data.w_vector.x.toFloat(), data.w_vector.y.toFloat(), data.w_vector.z.toFloat(), + data.distance.toFloat() + ) + }.toTypedArray() + + return Dataset(features, trainingData.map { data -> + data.delta.x + }.toFloatArray(), trainingData.map { data -> + data.delta.y + }.toFloatArray()) +} + +fun createAndTrainModel(features: Array, labels: FloatArray): Sequential { + val model = Sequential.of( + Input(7), + Dense(64, Activations.Relu, kernelInitializer = HeNormal()), + Dense(32, Activations.Relu, kernelInitializer = HeNormal()), + Dense(1, Activations.Linear) + ) + + val dataset = OnHeapDataset.create(features, labels) + + model.compile( + optimizer = Adam(), + loss = Losses.MSE, + metric = Metrics.MAE + ) + + model.fit( + dataset = dataset, + epochs = 100, + batchSize = 32 + ) + + return model +} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt index b9584220557..31e536acb79 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt @@ -28,10 +28,9 @@ import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.render.renderEnvironmentForWorld import net.ccbluex.liquidbounce.utils.aiming.PointTracker import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.data.VecRotation -import net.ccbluex.liquidbounce.utils.aiming.features.UpRamp +import net.ccbluex.liquidbounce.utils.aiming.data.RotationWithVector import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.LinearAngleSmoothMode -import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.SigmoidAngleSmoothMode +import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.TensorflowSmoothMode import net.ccbluex.liquidbounce.utils.aiming.preference.LeastDifferencePreference import net.ccbluex.liquidbounce.utils.aiming.utils.raytraceBox import net.ccbluex.liquidbounce.utils.aiming.utils.setRotation @@ -71,12 +70,10 @@ object ModuleAimbot : ClientModule("Aimbot", Category.COMBAT, aliases = arrayOf( private var angleSmooth = choices(this, "AngleSmooth") { arrayOf( LinearAngleSmoothMode(it), - SigmoidAngleSmoothMode(it) + TensorflowSmoothMode(it) ) } - private val upRamp = tree(UpRamp(this)) - private val ignoreOpenScreen by boolean("IgnoreOpenScreen", false) private val ignoreOpenContainer by boolean("IgnoreOpenContainer", false) @@ -98,7 +95,6 @@ object ModuleAimbot : ClientModule("Aimbot", Category.COMBAT, aliases = arrayOf( targetRotation = findNextTargetRotation()?.let { (target, rotation) -> angleSmooth.activeChoice.limitAngleChange( - upRamp.rotationFactor, player.rotation, rotation.rotation, rotation.vec, @@ -161,7 +157,7 @@ object ModuleAimbot : ClientModule("Aimbot", Category.COMBAT, aliases = arrayOf( } } - private fun findNextTargetRotation(): Pair? { + private fun findNextTargetRotation(): Pair? { for (target in targetTracker.targets()) { val pointOnHitbox = pointTracker.gatherPoint(target, PointTracker.AimSituation.FOR_NOW) val rotationPreference = LeastDifferencePreference(player.rotation, pointOnHitbox.toPoint) @@ -178,9 +174,6 @@ object ModuleAimbot : ClientModule("Aimbot", Category.COMBAT, aliases = arrayOf( rotationPreference = rotationPreference ) ?: continue - if (target != targetTracker.target) { - upRamp.onTrigger() - } targetTracker.target = target return target to spot } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/aimbot/autobow/AutoBowAutoShootFeature.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/aimbot/autobow/AutoBowAutoShootFeature.kt index cb018370805..896a3c9f1da 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/aimbot/autobow/AutoBowAutoShootFeature.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/aimbot/autobow/AutoBowAutoShootFeature.kt @@ -85,7 +85,7 @@ object AutoBowAutoShootFeature : ToggleableConfigurable(ModuleAutoBow, "AutoShoo return@handler } - val targetRotation = RotationManager.workingRotationTarget ?: return@handler + val targetRotation = RotationManager.activeRotationTarget ?: return@handler val aimDifference = RotationManager.serverRotation.angleTo(targetRotation.rotation) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/place/SubmoduleCrystalPlacer.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/place/SubmoduleCrystalPlacer.kt index d8954bd3deb..bf4bf92b0bf 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/place/SubmoduleCrystalPlacer.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/place/SubmoduleCrystalPlacer.kt @@ -26,7 +26,7 @@ import net.ccbluex.liquidbounce.render.engine.Color4b import net.ccbluex.liquidbounce.utils.aiming.NoRotationMode import net.ccbluex.liquidbounce.utils.aiming.RotationManager import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.data.VecRotation +import net.ccbluex.liquidbounce.utils.aiming.data.RotationWithVector import net.ccbluex.liquidbounce.utils.aiming.utils.findClosestPointOnBlockInLineWithCrystal import net.ccbluex.liquidbounce.utils.aiming.utils.raytraceBlock import net.ccbluex.liquidbounce.utils.aiming.utils.raytraceUpperBlockSide @@ -150,7 +150,7 @@ object SubmoduleCrystalPlacer : ToggleableConfigurable(ModuleCrystalAura, "Place queuePlacing(rotation, targetPos, side) } - private fun queuePlacing(rotation: VecRotation, targetPos: BlockPos, side: Direction) { + private fun queuePlacing(rotation: RotationWithVector, targetPos: BlockPos, side: Direction) { ModuleCrystalAura.rotationMode.activeChoice.rotate(rotation.rotation, isFinished = { blockHitResult = raytraceBlock( getMaxRange().toDouble(), @@ -180,7 +180,7 @@ object SubmoduleCrystalPlacer : ToggleableConfigurable(ModuleCrystalAura, "Place }) } - private fun updatePrevious(rotation: VecRotation) { + private fun updatePrevious(rotation: RotationWithVector) { if (previousRotations.size == 2) { previousRotations.removeFirst() } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt index 6523d114fb0..704506cf5e7 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt @@ -52,7 +52,7 @@ import net.ccbluex.liquidbounce.utils.aiming.PointTracker import net.ccbluex.liquidbounce.utils.aiming.RotationManager import net.ccbluex.liquidbounce.utils.aiming.RotationsConfigurable import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.data.VecRotation +import net.ccbluex.liquidbounce.utils.aiming.data.RotationWithVector import net.ccbluex.liquidbounce.utils.aiming.preference.LeastDifferencePreference import net.ccbluex.liquidbounce.utils.aiming.utils.facingEnemy import net.ccbluex.liquidbounce.utils.aiming.utils.raytraceBox @@ -423,7 +423,7 @@ object ModuleKillAura : ClientModule("KillAura", Category.COMBAT) { * * @return The best spot to attack the entity */ - private fun getSpot(entity: LivingEntity, range: Double, situation: PointTracker.AimSituation): VecRotation? { + private fun getSpot(entity: LivingEntity, range: Double, situation: PointTracker.AimSituation): RotationWithVector? { val point = pointTracker.gatherPoint( entity, situation diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/debugrecorder/modes/AimDebugRecorder.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/debugrecorder/modes/AimDebugRecorder.kt index 5e2a2d5457a..94730ab3e25 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/debugrecorder/modes/AimDebugRecorder.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/debugrecorder/modes/AimDebugRecorder.kt @@ -22,78 +22,58 @@ package net.ccbluex.liquidbounce.features.module.modules.misc.debugrecorder.modes import com.google.gson.JsonObject +import net.ccbluex.liquidbounce.config.gson.util.json import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.modules.misc.debugrecorder.ModuleDebugRecorder import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.combat.shouldBeAttacked -import net.ccbluex.liquidbounce.utils.entity.box +import net.ccbluex.liquidbounce.utils.client.FloatValueProvider +import net.ccbluex.liquidbounce.utils.combat.TargetPriority +import net.ccbluex.liquidbounce.utils.combat.TargetTracker import net.ccbluex.liquidbounce.utils.entity.lastRotation -import net.ccbluex.liquidbounce.utils.entity.prevPos import net.ccbluex.liquidbounce.utils.entity.rotation -import net.ccbluex.liquidbounce.utils.math.minus +import net.ccbluex.liquidbounce.utils.entity.squaredBoxedDistanceTo import net.minecraft.util.hit.EntityHitResult import net.minecraft.util.hit.HitResult object AimDebugRecorder : ModuleDebugRecorder.DebugRecorderMode("Aim") { - val repeatable = tickHandler { + private val targetTracker = TargetTracker(TargetPriority.DIRECTION, FloatValueProvider("Range", 7f, 4f..10f)) + + @Suppress("unused") + private val tickHandler = tickHandler { val playerRotation = player.rotation val playerLastRotation = player.lastRotation - + val target = targetTracker.selectFirst() ?: return@tickHandler val turnSpeed = playerLastRotation.rotationDeltaTo(playerRotation) - val crosshairTarget = mc.crosshairTarget - recordPacket(JsonObject().apply { - addProperty("health", player.health) - addProperty("yaw", playerRotation.yaw) - addProperty("pitch", playerRotation.pitch) - addProperty("last_yaw", playerLastRotation.yaw) - addProperty("last_pitch", playerLastRotation.pitch) - addProperty("turn_speed_h", turnSpeed.deltaYaw) - addProperty("turn_speed_v", turnSpeed.deltaPitch) - - add("velocity", JsonObject().apply { - addProperty("x", player.velocity.x) - addProperty("y", player.velocity.y) - addProperty("z", player.velocity.z) + val cDirVec = player.rotation.directionVector + add("c_vector", json { + "x" to cDirVec.x + "y" to cDirVec.y + "z" to cDirVec.z }) + val rotation = Rotation.lookingAt(point = target.eyePos, from = player.eyePos) + val wDirVec = rotation.directionVector + add("w_vector", json { + "x" to wDirVec.x + "y" to wDirVec.y + "z" to wDirVec.z + }) + add("delta", json { + "x" to turnSpeed.deltaYaw + "y" to turnSpeed.deltaPitch + }) + addProperty("distance", player.squaredBoxedDistanceTo(target)) - world.entities.filter { - it.shouldBeAttacked() && it.distanceTo(player) < 10.0f - }.minByOrNull { - it.distanceTo(player) - }?.let { - val vector = it.pos - player.pos - add("vec", JsonObject().apply { - addProperty("x", vector.x) - addProperty("y", vector.y) - addProperty("z", vector.z) - }) - val velocity = it.pos - it.prevPos - add("velocity", JsonObject().apply { - addProperty("x", velocity.x) - addProperty("y", velocity.y) - addProperty("z", velocity.z) - }) - addProperty("distance", player.distanceTo(it)) - val rotation = Rotation.lookingAt(point = it.box.center, from = player.eyePos) - - val delta = rotation.rotationDeltaTo(playerRotation) - - addProperty("diff_h", delta.deltaYaw) - addProperty("diff_v", delta.deltaPitch) - addProperty("yaw_target", rotation.yaw) - addProperty("pitch_target", rotation.pitch) - - addProperty("crosshair", - if (crosshairTarget?.type == HitResult.Type.ENTITY && crosshairTarget is EntityHitResult) { - crosshairTarget.entity.id == it.id - } else { - false - } - ) - } + val crosshairTarget = mc.crosshairTarget + addProperty("reward", + if (crosshairTarget?.type == HitResult.Type.ENTITY && crosshairTarget is EntityHitResult) { + crosshairTarget.entity.id == target.id + } else { + false + } + ) }) } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleSprint.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleSprint.kt index 76f1f1e9b8e..3ef1429ecb7 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleSprint.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleSprint.kt @@ -122,7 +122,7 @@ object ModuleSprint : ClientModule("Sprint", Category.MOVEMENT) { MathHelper.sin(deltaYaw * 0.017453292f) > 1.0E-5 val preventSprint = (if (player.isOnGround) stopOnGround else stopOnAir) && !shouldSprintOmnidirectional - && RotationManager.workingRotationTarget?.movementCorrection == MovementCorrection.OFF + && RotationManager.activeRotationTarget?.movementCorrection == MovementCorrection.OFF && !hasForwardMovement return running && preventSprint diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/trajectories/ModuleTrajectories.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/trajectories/ModuleTrajectories.kt index bbe6554a393..d624222f8e4 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/trajectories/ModuleTrajectories.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/trajectories/ModuleTrajectories.kt @@ -95,7 +95,7 @@ object ModuleTrajectories : ClientModule("Trajectories", Category.RENDER) { if (ModuleFreeCam.running) { RotationManager.serverRotation } else { - RotationManager.workingRotationTarget?.rotation + RotationManager.activeRotationTarget?.rotation ?: RotationManager.currentRotation ?: otherPlayer.rotation } } else { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt index e66ea03b3e6..22584aec246 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt @@ -59,7 +59,7 @@ object RotationManager : EventListener { get() = rotationTargetHandler.getActiveRequestValue() private var rotationTargetHandler = RequestHandler() - val workingRotationTarget: RotationTarget? + val activeRotationTarget: RotationTarget? get() = rotationTarget ?: previousRotationTarget private var previousRotationTarget: RotationTarget? = null @@ -132,34 +132,24 @@ object RotationManager : EventListener { */ @Suppress("CognitiveComplexMethod", "NestedBlockDepth") fun update() { - val workingAimPlan = this.workingRotationTarget ?: return + val activeTarget = this.activeRotationTarget ?: return val playerRotation = player.rotation - - val aimPlan = this.rotationTarget - if (aimPlan != null) { - val enemyChange = aimPlan.entity != null && aimPlan.entity != previousRotationTarget?.entity && - aimPlan.upRamp?.onEnemyChange == true - val triggerNoChange = triggerNoDifference && aimPlan.upRamp?.onZeroRotationDifference == true - - if (triggerNoChange || enemyChange) { - aimPlan.upRamp?.onTrigger() - } - } + val rotationTarget = this.rotationTarget // Prevents any rotation changes when inventory is opened val allowedRotation = ((!InventoryManager.isInventoryOpen && - mc.currentScreen !is GenericContainerScreen) || !workingAimPlan.considerInventory) && allowedToUpdate() + mc.currentScreen !is GenericContainerScreen) || !activeTarget.considerInventory) && allowedToUpdate() if (allowedRotation) { val fromRotation = currentRotation ?: playerRotation - val rotation = workingAimPlan.nextRotation(fromRotation, aimPlan == null) + val rotation = activeTarget.nextRotation(fromRotation, rotationTarget == null) // After generating the next rotation, we need to normalize it .normalize() val diff = rotation.angleTo(playerRotation) - if (aimPlan == null && (workingAimPlan.movementCorrection == MovementCorrection.CHANGE_LOOK - || diff <= workingAimPlan.resetThreshold)) { + if (rotationTarget == null && (activeTarget.movementCorrection == MovementCorrection.CHANGE_LOOK + || diff <= activeTarget.resetThreshold)) { currentRotation?.let { currentRotation -> player.yaw = player.withFixedYaw(currentRotation) player.renderYaw = player.yaw @@ -169,14 +159,14 @@ object RotationManager : EventListener { currentRotation = null previousRotationTarget = null } else { - if (workingAimPlan.movementCorrection == MovementCorrection.CHANGE_LOOK) { + if (activeTarget.movementCorrection == MovementCorrection.CHANGE_LOOK) { player.setRotation(rotation) } currentRotation = rotation - previousRotationTarget = workingAimPlan + previousRotationTarget = activeTarget - aimPlan?.whenReached?.invoke() + rotationTarget?.whenReached?.invoke() } } @@ -201,7 +191,7 @@ object RotationManager : EventListener { @Suppress("unused") private val velocityHandler = handler { event -> - if (workingRotationTarget?.movementCorrection != MovementCorrection.OFF) { + if (activeRotationTarget?.movementCorrection != MovementCorrection.OFF) { val rotation = currentRotation ?: return@handler event.velocity = Entity.movementInputToVelocity( @@ -237,17 +227,7 @@ object RotationManager : EventListener { priority = EventPriorityConvention.READ_FINAL_STATE ) { event -> val rotation = when (val packet = event.packet) { - is PlayerMoveC2SPacket -> { - // If we are not changing the look, we don't need to update the rotation - // but, we want to handle slow start triggers - if (!packet.changeLook) { - triggerNoDifference = true - return@handler - } - - // We trust that we have sent a normalized rotation, if not, ... why? - Rotation(packet.yaw, packet.pitch, isNormalized = true) - } + is PlayerMoveC2SPacket -> Rotation(packet.yaw, packet.pitch, isNormalized = true) is PlayerPositionLookS2CPacket -> Rotation(packet.change.yaw, packet.change.pitch, isNormalized = true) is PlayerInteractItemC2SPacket -> Rotation(packet.yaw, packet.pitch, isNormalized = true) else -> return@handler diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationTarget.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationTarget.kt index bd84516e281..f8896bcd35a 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationTarget.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationTarget.kt @@ -19,10 +19,8 @@ package net.ccbluex.liquidbounce.utils.aiming import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.features.FailFocus import net.ccbluex.liquidbounce.utils.aiming.features.MovementCorrection import net.ccbluex.liquidbounce.utils.aiming.features.ShortStop -import net.ccbluex.liquidbounce.utils.aiming.features.UpRamp import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.AngleSmoothMode import net.ccbluex.liquidbounce.utils.client.RestrictedSingleUseAction import net.ccbluex.liquidbounce.utils.client.player @@ -46,8 +44,6 @@ class RotationTarget( * If we do not want to smooth the angle, we can set this to null. */ val angleSmooth: AngleSmoothMode?, - val upRamp: UpRamp?, - val failFocus: FailFocus?, val shortStop: ShortStop?, val ticksUntilReset: Int, /** @@ -79,23 +75,11 @@ class RotationTarget( } val angleSmooth = angleSmooth ?: return rotation - val factorModifier = if (failFocus?.isInFailState == true) { - failFocus.failFactor - } else { - upRamp?.rotationFactor ?: 1f - } if (isResetting) { - return angleSmooth.limitAngleChange(factorModifier, fromRotation, player.rotation) - } - - val rotation = if (failFocus?.isInFailState == true) { - failFocus.shiftRotation(rotation) - } else { - rotation + return angleSmooth.limitAngleChange(fromRotation, player.rotation) } - - return angleSmooth.limitAngleChange(factorModifier, fromRotation, rotation, vec3d, entity) + return angleSmooth.limitAngleChange(fromRotation, rotation, vec3d, entity) } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt index bdbcf19236f..827e6253753 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt @@ -3,11 +3,12 @@ package net.ccbluex.liquidbounce.utils.aiming import net.ccbluex.liquidbounce.config.types.Configurable import net.ccbluex.liquidbounce.event.EventListener import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.features.FailFocus import net.ccbluex.liquidbounce.utils.aiming.features.MovementCorrection import net.ccbluex.liquidbounce.utils.aiming.features.ShortStop -import net.ccbluex.liquidbounce.utils.aiming.features.UpRamp -import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.* +import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.AccelerationSmoothMode +import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.ConditionalLinearAngleSmoothMode +import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.LinearAngleSmoothMode +import net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth.TensorflowSmoothMode import net.ccbluex.liquidbounce.utils.client.RestrictedSingleUseAction import net.minecraft.entity.Entity import net.minecraft.util.math.Vec3d @@ -24,16 +25,13 @@ open class RotationsConfigurable( private val angleSmooth = choices(owner, "AngleSmooth", 0) { arrayOf( LinearAngleSmoothMode(it), - BezierAngleSmoothMode(it), - SigmoidAngleSmoothMode(it), + TensorflowSmoothMode(it), ConditionalLinearAngleSmoothMode(it), AccelerationSmoothMode(it) ) } - private var upRamp = UpRamp(owner).takeIf { combatSpecific }?.also { tree(it) } private var shortStop = ShortStop(owner).takeIf { combatSpecific }?.also { tree(it) } - private val failFocus = FailFocus(owner).takeIf { combatSpecific }?.also { tree(it) } private val movementCorrection by enumChoice("MovementCorrection", movementCorrection) private val resetThreshold by float("ResetThreshold", 2f, 1f..180f) @@ -50,8 +48,6 @@ open class RotationsConfigurable( vec, entity, angleSmooth.activeChoice, - upRamp, - failFocus, shortStop, ticksUntilReset, resetThreshold, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/VecRotation.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/RotationWithVector.kt similarity index 92% rename from src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/VecRotation.kt rename to src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/RotationWithVector.kt index 7d1c69515e5..eed3ea6bbea 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/VecRotation.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/data/RotationWithVector.kt @@ -20,4 +20,4 @@ package net.ccbluex.liquidbounce.utils.aiming.data import net.minecraft.util.math.Vec3d -data class VecRotation(val rotation: Rotation, val vec: Vec3d) +data class RotationWithVector(val rotation: Rotation, val vec: Vec3d) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/FailFocus.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/FailFocus.kt deleted file mode 100644 index 2f1ec1db98e..00000000000 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/FailFocus.kt +++ /dev/null @@ -1,94 +0,0 @@ -package net.ccbluex.liquidbounce.utils.aiming.features - -import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable -import net.ccbluex.liquidbounce.event.EventListener -import net.ccbluex.liquidbounce.event.events.GameTickEvent -import net.ccbluex.liquidbounce.event.handler -import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug -import net.ccbluex.liquidbounce.utils.aiming.RotationManager -import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention -import net.ccbluex.liquidbounce.utils.kotlin.random -import kotlin.random.Random - -/** - * The fail focus acts as fail rate, it will purposely miss the target on a certain rate. - */ -class FailFocus(owner: EventListener? = null) - : ToggleableConfigurable(owner, "Fail", false) { - - // Configuration properties - private val failRate by int("Rate", 3, 1..100, "%") - val failFactor by float("Factor", 0.04f, 0.01f..0.99f) - - private val strengthHorizontal by floatRange("StrengthHorizontal", 15f..20f, 1f..90f, - "°") - private val strengthVertical by floatRange("StrengthVertical", 2f..5f, 0f..90f, - "°") - - /** - * The duration it takes to transition from the fail factor to the normal factor. - */ - private var transitionInDuration by intRange("TransitionInDuration", 1..4, 0..20, - "ticks") - - // A tick meter to track the duration for which the current target has been focused on - private var ticksElapsed = 0 - - // The currently set transition duration, randomized within the defined range - private var currentTransitionInDuration = transitionInDuration.random() - - // The shift rotation - private var shiftRotation = Rotation(0f, 0f) - - val isInFailState: Boolean - get() = enabled && ticksElapsed < currentTransitionInDuration - - @Suppress("unused") - private val gameTick = handler(priority = EventPriorityConvention.FIRST_PRIORITY) { - // Fail rate - val chance = (0f..100f).random() - if (failRate > chance) { - currentTransitionInDuration = transitionInDuration.random() - val yawShift = if (Random.Default.nextBoolean()) { - strengthHorizontal.random().toFloat() - } else { - -strengthHorizontal.random().toFloat() - } - - val pitchShift = if (Random.Default.nextBoolean()) { - strengthVertical.random().toFloat() - } else { - -strengthVertical.random().toFloat() - } - - shiftRotation = Rotation(yawShift, pitchShift) - ticksElapsed = 0 - - ModuleDebug.debugParameter(this, "Chance", chance) - ModuleDebug.debugParameter(this, "Duration", currentTransitionInDuration) - ModuleDebug.debugParameter(this, "Shift", shiftRotation) - } else { - ticksElapsed++ - } - - ModuleDebug.debugParameter(this, "Elapsed", ticksElapsed) - } - - /** - * Generates a complete non-sense rotation. - */ - fun shiftRotation(rotation: Rotation): Rotation { - val prevRotation = RotationManager.previousRotation ?: return rotation - val serverRotation = RotationManager.serverRotation - - val deltaYaw = (prevRotation.yaw - serverRotation.yaw) * failFactor - val deltaPitch = (prevRotation.pitch - serverRotation.pitch) * failFactor - - return Rotation( - rotation.yaw + deltaYaw + shiftRotation.yaw, - rotation.pitch + deltaPitch + shiftRotation.pitch - ) - } - -} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/ShortStop.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/ShortStop.kt index 824259bb063..7ff61786021 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/ShortStop.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/ShortStop.kt @@ -22,7 +22,7 @@ class ShortStop(owner: EventListener? = null) // The currently set transition duration, randomized within the defined range private var currentTransitionInDuration = stopDuration.random() val isInStopState: Boolean - get() = enabled && ticksElapsed < currentTransitionInDuration + get() = running && ticksElapsed < currentTransitionInDuration @Suppress("unused") private val gameHandler = handler(priority = FIRST_PRIORITY) { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/UpRamp.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/UpRamp.kt deleted file mode 100644 index 99264451b84..00000000000 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/UpRamp.kt +++ /dev/null @@ -1,65 +0,0 @@ -package net.ccbluex.liquidbounce.utils.aiming.features - -import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable -import net.ccbluex.liquidbounce.event.EventListener -import net.ccbluex.liquidbounce.event.events.GameTickEvent -import net.ccbluex.liquidbounce.event.handler -import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention.FIRST_PRIORITY - -/** - * The up ramp modulates the rotation speed based on the time duration - * a target has been focused on. Initially, the rotation speed is reduced to smoothly - * transition to a new target and gradually increases to normal speed. This method - * enhances aiming by providing smooth adjustments, particularly for fast-moving targets, - * avoiding abrupt or unnatural flicks. - */ -class UpRamp(owner: EventListener? = null) - : ToggleableConfigurable(owner, "UpRamp", false, aliases = arrayOf("SlowStart")) { - - // Configuration properties - private val slowStartFactor by float("SlowStartFactor", 0.6f, 0.01f..0.99f) - private val transitionDuration by intRange("TransitionDuration", 1..3, 1..20, - "ticks") - - // Triggers - val onEnemyChange by boolean("OnEnemyChange", true) - val onZeroRotationDifference by boolean("OnZeroRotationDifference", false) - - // A tick meter to track the duration for which the current target has been focused on - private var ticksElapsed = 0 - - // The currently set transition duration, randomized within the defined range - private var currentTransitionDuration = transitionDuration.random() - - /** - * The rotation factor is multiplied with the rotation speed to initially slow down - * the rotation when focusing on a new target, gradually increasing to normal speed. - */ - val rotationFactor: Float - get() { - if (!enabled) { - return 1f - } - - val elapsed = ticksElapsed - return if (elapsed <= currentTransitionDuration) { - slowStartFactor + (1 - slowStartFactor) * (elapsed.toFloat() / currentTransitionDuration.toFloat()) - } else { - 1f - } - } - - @Suppress("unused") - private val gameHandler = handler(priority = FIRST_PRIORITY) { - ticksElapsed++ - } - - /** - * Resets the chronometer and sets a new randomized transition duration when a trigger event occurs. - */ - fun onTrigger() { - currentTransitionDuration = transitionDuration.random() - ticksElapsed = 0 - } - -} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt index c470d1d2793..eb6d86c20dd 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt @@ -97,7 +97,6 @@ class AccelerationSmoothMode(override val parent: ChoiceConfigurable<*>) : Angle } override fun limitAngleChange( - factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt index e7ade0b09b2..4a6960b3521 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt @@ -31,7 +31,6 @@ import net.minecraft.util.math.Vec3d */ abstract class AngleSmoothMode(name: String) : Choice(name) { abstract fun limitAngleChange( - factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d? = null, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt deleted file mode 100644 index 2306e704d5c..00000000000 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce) - * - * Copyright (c) 2015 - 2025 CCBlueX - * - * LiquidBounce is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LiquidBounce is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LiquidBounce. If not, see . - * - */ -package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth - -import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable -import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.kotlin.random -import net.minecraft.entity.Entity -import net.minecraft.util.math.Vec3d -import kotlin.math.abs -import kotlin.math.min - -class BezierAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSmoothMode("Bezier") { - private val horizontalTurnSpeed by floatRange("HorizontalTurnSpeed", 180f..180f, 0.0f..180f) - private val verticalTurnSpeed by floatRange("VerticalTurnSpeed", 180f..180f, 0.0f..180f) - private val controlPoint by float("ControlPoint", 0.5f, 0.0f..1.0f) - - override fun limitAngleChange( - factorModifier: Float, - currentRotation: Rotation, - targetRotation: Rotation, - vec3d: Vec3d?, - entity: Entity? - ): Rotation { - val diff = currentRotation.rotationDeltaTo(targetRotation) - val rotationDifference = diff.length() - - val (factorH, factorV) = computeFactor(rotationDifference, horizontalTurnSpeed.random()) to - computeFactor(rotationDifference, verticalTurnSpeed.random()) - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) - - return Rotation( - currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), - currentRotation.pitch + diff.deltaPitch.coerceIn(-straightLinePitch, straightLinePitch) - ) - } - - override fun howLongToReach(currentRotation: Rotation, targetRotation: Rotation): Int { - val diff = currentRotation.rotationDeltaTo(targetRotation) - val rotationDifference = diff.length() - - val (factorH, factorV) = computeFactor(rotationDifference, horizontalTurnSpeed.random()) to - computeFactor(rotationDifference, verticalTurnSpeed.random()) - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV - return (rotationDifference / min(straightLineYaw, straightLinePitch)).toInt() - } - - private fun computeFactor(rotationDifference: Float, turnSpeed: Double): Float { - val t = (rotationDifference / 180).coerceIn(0f, 1f) - - val bezierSpeed = bezierInterpolate(0f, controlPoint, 1f, 1 - t) * turnSpeed - - return bezierSpeed.toFloat() - .coerceAtLeast(0f) - .coerceAtMost(180f) - } - - private fun bezierInterpolate(start: Float, control: Float, end: Float, t: Float): Float { - return (1 - t) * (1 - t) * start + 2 * (1 - t) * t * control + t * t * end - } -} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt index 7a5f0640425..929b6ac74e9 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt @@ -51,7 +51,6 @@ class ConditionalLinearAngleSmoothMode(override val parent: ChoiceConfigurable<* private val failIncrementV by float("FailIncrementV", 0f, 0.0f..10f) override fun limitAngleChange( - factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, @@ -71,9 +70,9 @@ class ConditionalLinearAngleSmoothMode(override val parent: ChoiceConfigurable<* crosshair, ) - val straightLineYaw = max(abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier), + val straightLineYaw = max(abs(diff.deltaYaw / rotationDifference) * factorH, minimumTurnSpeedH) - val straightLinePitch = max(abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier), + val straightLinePitch = max(abs(diff.deltaPitch / rotationDifference) * factorV, minimumTurnSpeedV) return Rotation( diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt index 88c578ace17..b700226a322 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt @@ -38,7 +38,6 @@ class LinearAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleS 0.0f..180f) override fun limitAngleChange( - factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, @@ -50,8 +49,8 @@ class LinearAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleS val (factorH, factorV) = horizontalTurnSpeed.random().toFloat() to verticalTurnSpeed.random().toFloat() - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV return Rotation( currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt deleted file mode 100644 index a3384b88b1b..00000000000 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce) - * - * Copyright (c) 2015 - 2025 CCBlueX - * - * LiquidBounce is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * LiquidBounce is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LiquidBounce. If not, see . - * - * - */ - -package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth - -import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable -import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.kotlin.random -import net.minecraft.entity.Entity -import net.minecraft.util.math.Vec3d -import kotlin.math.abs -import kotlin.math.exp -import kotlin.math.min - -class SigmoidAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSmoothMode("Sigmoid") { - - private val horizontalTurnSpeed by floatRange("HorizontalTurnSpeed", 180f..180f, - 0.0f..180f) - private val verticalTurnSpeed by floatRange("VerticalTurnSpeed", 180f..180f, - 0.0f..180f) - - private val steepness by float("Steepness", 10f, 0.0f..20f) - private val midpoint by float("Midpoint", 0.3f, 0.0f..1.0f) - - override fun limitAngleChange( - factorModifier: Float, - currentRotation: Rotation, - targetRotation: Rotation, - vec3d: Vec3d?, - entity: Entity? - ): Rotation { - val diff = currentRotation.rotationDeltaTo(targetRotation) - - val rotationDifference = diff.length() - - val (factorH, factorV) = - computeFactor(rotationDifference, horizontalTurnSpeed.random()) to - computeFactor(rotationDifference, verticalTurnSpeed.random()) - - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) - - return Rotation( - currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), - currentRotation.pitch + diff.deltaPitch.coerceIn(-straightLinePitch, straightLinePitch) - ) - } - - override fun howLongToReach(currentRotation: Rotation, targetRotation: Rotation): Int { - val diff = currentRotation.rotationDeltaTo(targetRotation) - - val rotationDifference = diff.length() - - val (factorH, factorV) = - computeFactor(rotationDifference, horizontalTurnSpeed.random()) to - computeFactor(rotationDifference, verticalTurnSpeed.random()) - - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV - - return (rotationDifference / min(straightLineYaw, straightLinePitch)).toInt() - } - - private fun computeFactor(rotationDifference: Float, turnSpeed: Double): Float { - // Scale the rotation difference to fit within a reasonable range - val scaledDifference = rotationDifference / 120f - - // Compute the sigmoid function - val sigmoid = 1 / (1 + exp((-steepness * (scaledDifference - midpoint)).toDouble())) - - // Interpolate sigmoid value to fit within the range of turnSpeed - val interpolatedSpeed = sigmoid * turnSpeed - - return interpolatedSpeed.toFloat() - .coerceAtLeast(0f) - .coerceAtMost(180f) - } - -} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt new file mode 100644 index 00000000000..7f6ea8e6d76 --- /dev/null +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt @@ -0,0 +1,94 @@ +package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth + +import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.utils.aiming.data.Rotation +import net.ccbluex.liquidbounce.utils.client.chat +import net.ccbluex.liquidbounce.utils.entity.boxedDistanceTo +import net.minecraft.entity.Entity +import net.minecraft.util.math.Vec3d +import org.jetbrains.kotlinx.dl.api.core.Sequential +import org.jetbrains.kotlinx.dl.api.core.activation.Activations +import org.jetbrains.kotlinx.dl.api.core.initializer.HeNormal +import org.jetbrains.kotlinx.dl.api.core.layer.core.Dense +import org.jetbrains.kotlinx.dl.api.core.layer.core.Input +import org.jetbrains.kotlinx.dl.api.core.loss.Losses +import org.jetbrains.kotlinx.dl.api.core.metric.Metrics +import org.jetbrains.kotlinx.dl.api.core.optimizer.Adam +import java.io.File + +class TensorflowSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSmoothMode("Tensorflow") { + + companion object { + + init { + // Load TensorFlow JNI libraries from /run directory + System.load(File("./libtensorflow_framework.so.1").absolutePath) + System.load(File("./libtensorflow_jni.so").absolutePath) + } + + // TODO: How do I combine these two models into one? + private val yawModel: Sequential = loadModel("./models/yaw_model") + private val pitchModel: Sequential = loadModel("./models/pitch_model") + + private fun loadModel(path: String): Sequential { + return Sequential.of( + Input(7), + Dense(64, Activations.Relu, kernelInitializer = HeNormal()), + Dense(32, Activations.Relu, kernelInitializer = HeNormal()), + Dense(1, Activations.Linear) + ).also { model -> + model.compile( + optimizer = Adam(), + loss = Losses.MSE, + metric = Metrics.MAE + ) + model.loadWeights(File(path), true) + } + } + + } + + override fun limitAngleChange( + currentRotation: Rotation, + targetRotation: Rotation, + vec3d: Vec3d?, + entity: Entity? + ): Rotation { + /** + * floatArrayOf( + * data.c_vector.x.toFloat(), data.c_vector.y.toFloat(), data.c_vector.z.toFloat(), + * data.w_vector.x.toFloat(), data.w_vector.y.toFloat(), data.w_vector.z.toFloat(), + * data.distance.toFloat() + * ) + */ + val c_vector = currentRotation.directionVector + val w_vector = targetRotation.directionVector + val distance = entity?.let { entity -> player.boxedDistanceTo(entity) } ?: 0.0 + + val predictedYaw = yawModel.predictSoftly(floatArrayOf( + c_vector.x.toFloat(), c_vector.y.toFloat(), c_vector.z.toFloat(), + w_vector.x.toFloat(), w_vector.y.toFloat(), w_vector.z.toFloat(), + distance.toFloat() + ))[0] + + val predictedPitch = pitchModel.predictSoftly(floatArrayOf( + c_vector.x.toFloat(), c_vector.y.toFloat(), c_vector.z.toFloat(), + w_vector.x.toFloat(), w_vector.y.toFloat(), w_vector.z.toFloat(), + distance.toFloat() + ))[0] + chat("TensorFlow -> Yaw: $predictedYaw, Pitch: $predictedPitch") + + return Rotation( + currentRotation.yaw + predictedYaw, + currentRotation.pitch + predictedPitch + ) + } + + override fun howLongToReach( + currentRotation: Rotation, + targetRotation: Rotation + ): Int { + return 0 + } + +} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/utils/RotationFinding.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/utils/RotationFinding.kt index fbbebf95504..047d803d058 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/utils/RotationFinding.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/utils/RotationFinding.kt @@ -28,7 +28,7 @@ import net.ccbluex.liquidbounce.render.FULL_BOX import net.ccbluex.liquidbounce.render.engine.Color4b import net.ccbluex.liquidbounce.utils.aiming.RotationManager import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.aiming.data.VecRotation +import net.ccbluex.liquidbounce.utils.aiming.data.RotationWithVector import net.ccbluex.liquidbounce.utils.aiming.preference.LeastDifferencePreference import net.ccbluex.liquidbounce.utils.aiming.preference.RotationPreference import net.ccbluex.liquidbounce.utils.block.getState @@ -55,7 +55,7 @@ fun raytraceBlock( state: BlockState, range: Double, wallsRange: Double, -): VecRotation? { +): RotationWithVector? { val offset = Vec3d(pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble()) val shape = state.getOutlineShape(world, pos, ShapeContext.of(player)) @@ -119,12 +119,12 @@ fun canSeeUpperBlockSide( private open class BestRotationTracker(val comparator: Comparator, val ignoreVisibility: Boolean = false) { - var bestInvisible: VecRotation? = null + var bestInvisible: RotationWithVector? = null private set - var bestVisible: VecRotation? = null + var bestVisible: RotationWithVector? = null private set - fun considerRotation(rotation: VecRotation, visible: Boolean = true) { + fun considerRotation(rotation: RotationWithVector, visible: Boolean = true) { if (visible || ignoreVisibility) { val isRotationBetter = getIsRotationBetter(base = this.bestVisible, rotation, true) @@ -140,7 +140,7 @@ private open class BestRotationTracker(val comparator: Comparator, val } } - protected open fun getIsRotationBetter(base: VecRotation?, newRotation: VecRotation, visible: Boolean): Boolean { + protected open fun getIsRotationBetter(base: RotationWithVector?, newRotation: RotationWithVector, visible: Boolean): Boolean { return base?.let { currentlyBest -> this.comparator.compare(currentlyBest.rotation, newRotation.rotation) > 0 } ?: true @@ -161,7 +161,7 @@ private class PrePlaningTracker( private val bestVisibleIntersects = false private val bestInvisibleIntersects = false - override fun getIsRotationBetter(base: VecRotation?, newRotation: VecRotation, visible: Boolean): Boolean { + override fun getIsRotationBetter(base: RotationWithVector?, newRotation: RotationWithVector, visible: Boolean): Boolean { val intersects = futureTarget.isHitByLine(eyes, newRotation.vec) val isBetterWhenVisible = visible && !bestVisibleIntersects @@ -232,7 +232,7 @@ fun raytraceBlockSide( rangeSquared: Double, wallsRangeSquared: Double, shapeContext: ShapeContext -): VecRotation? { +): RotationWithVector? { pos.getState()?.getOutlineShape(world, pos, shapeContext)?.let { shape -> val sortedShapes = shape.boundingBoxes.sortedBy { -(it.maxX - it.minX) * (it.maxY - it.minY) * (it.maxZ - it.minZ) @@ -301,7 +301,7 @@ fun raytraceBox( rotationPreference: RotationPreference = LeastDifferencePreference.LEAST_DISTANCE_TO_CURRENT_ROTATION, futureTarget: Box? = null, prioritizeVisible: Boolean = true -): VecRotation? { +): RotationWithVector? { val rangeSquared = range * range val wallsRangeSquared = wallsRange * wallsRange @@ -322,7 +322,7 @@ fun raytraceBox( val validCauseVisible = visibilityPredicate.isVisible(eyesPos = eyes, targetSpot = preferredSpotOnBox) if (validCauseBelowWallsRange || validCauseVisible && preferredSpotDistance < rangeSquared) { - return VecRotation(Rotation.lookingAt(point = preferredSpot, from = eyes), preferredSpot) + return RotationWithVector(Rotation.lookingAt(point = preferredSpot, from = eyes), preferredSpot) } } @@ -391,7 +391,7 @@ private fun considerSpot( val rotation = Rotation.lookingAt(point = spot, from = eyes) - bestRotationTracker.considerRotation(VecRotation(rotation, spot), visible) + bestRotationTracker.considerRotation(RotationWithVector(rotation, spot), visible) } /** @@ -475,7 +475,7 @@ fun raytraceUpperBlockSide( expectedTarget: BlockPos, rotationPreference: RotationPreference = LeastDifferencePreference.LEAST_DISTANCE_TO_CURRENT_ROTATION, rotationsNotToMatch: List? = null -): VecRotation? { +): RotationWithVector? { val rangeSquared = range * range val wallsRangeSquared = wallsRange * wallsRange @@ -507,7 +507,7 @@ fun raytraceUpperBlockSide( return@range } - bestRotationTracker.considerRotation(VecRotation(rotation, vec3), visible) + bestRotationTracker.considerRotation(RotationWithVector(rotation, vec3), visible) } return bestRotationTracker.bestVisible ?: bestRotationTracker.bestInvisible @@ -531,8 +531,8 @@ fun findClosestPointOnBlockInLineWithCrystal( expectedTarget: BlockPos, notFacingAway: Boolean, rotationsNotToMatch: List? = null -): Pair? { - var best: Pair? = null +): Pair? { + var best: Pair? = null var bestIntersects = false var bestDistance = Double.MAX_VALUE @@ -596,7 +596,7 @@ fun findClosestPointOnBlockInLineWithCrystal( return@range } - best = VecRotation(rotation, vec3) to it + best = RotationWithVector(rotation, vec3) to it bestDistance = distance bestIntersects = intersects } @@ -611,7 +611,7 @@ private fun checkCurrentRotation( expectedTarget: BlockPos, predictedCrystal: Box, eyes: Vec3d -): Pair? { +): Pair? { val currentHit = raytraceBlock( max(range, wallsRange), RotationManager.serverRotation, @@ -632,7 +632,7 @@ private fun checkCurrentRotation( if (intersects && distance <= range.sq() && visibleThroughWalls) { val rotation = Rotation.lookingAt(point = pos, from = eyes) - return VecRotation(rotation, pos) to currentHit.side + return RotationWithVector(rotation, pos) to currentHit.side } return null From da6a1d4cedf25eee5e4ccb8281956d9ec1ad43cd Mon Sep 17 00:00:00 2001 From: Izuna Date: Sun, 16 Feb 2025 08:08:18 +0100 Subject: [PATCH 2/3] revert unrelated refactoring --- .../kotlin/{Train.kt => DataModelTrainer.kt} | 23 +++-- .../utils/aiming/RotationsConfigurable.kt | 3 +- .../anglesmooth/AccelerationSmoothMode.kt | 1 + .../features/anglesmooth/AngleSmoothMode.kt | 1 + .../anglesmooth/BezierAngleSmoothMode.kt | 80 +++++++++++++++ .../ConditionalLinearAngleSmoothMode.kt | 5 +- .../anglesmooth/LinearAngleSmoothMode.kt | 5 +- .../anglesmooth/SigmoidAngleSmoothMode.kt | 97 +++++++++++++++++++ .../anglesmooth/TestAngleSmoothMode.kt | 1 + 9 files changed, 205 insertions(+), 11 deletions(-) rename src/main/kotlin/{Train.kt => DataModelTrainer.kt} (87%) create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt create mode 100644 src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt diff --git a/src/main/kotlin/Train.kt b/src/main/kotlin/DataModelTrainer.kt similarity index 87% rename from src/main/kotlin/Train.kt rename to src/main/kotlin/DataModelTrainer.kt index 6e55b76fd31..87947bd09f7 100644 --- a/src/main/kotlin/Train.kt +++ b/src/main/kotlin/DataModelTrainer.kt @@ -1,4 +1,5 @@ import com.google.gson.Gson +import com.google.gson.annotations.SerializedName import com.google.gson.reflect.TypeToken import net.ccbluex.liquidbounce.utils.aiming.data.Rotation import net.ccbluex.liquidbounce.utils.kotlin.random @@ -19,8 +20,10 @@ import kotlin.math.abs data class Vector(val x: Double, val y: Double, val z: Double) data class Vec2f(val x: Float, val y: Float) data class TrainingData( - val c_vector: Vector, - val w_vector: Vector, + @SerializedName("c_vector") + val currentVector: Vector, + @SerializedName("w_vector") + val targetVector: Vector, val delta: Vec2f, val distance: Double ) @@ -78,8 +81,16 @@ fun generateTrainingData(): List { val diff2 = clientRotation.rotationDeltaTo(nextClientRotation) trainingData += TrainingData( - Vector(clientRotation.directionVector.x, clientRotation.directionVector.y, clientRotation.directionVector.z), - Vector(targetRotation.directionVector.x, targetRotation.directionVector.y, targetRotation.directionVector.z), + Vector( + clientRotation.directionVector.x, + clientRotation.directionVector.y, + clientRotation.directionVector.z + ), + Vector( + targetRotation.directionVector.x, + targetRotation.directionVector.y, + targetRotation.directionVector.z + ), Vec2f(diff2.deltaYaw, diff2.deltaPitch), distance ) @@ -134,8 +145,8 @@ data class Dataset(val features: Array, val labelX: FloatArray, val fun prepareData(trainingData: List): Dataset { val features = trainingData.map { data -> floatArrayOf( - data.c_vector.x.toFloat(), data.c_vector.y.toFloat(), data.c_vector.z.toFloat(), - data.w_vector.x.toFloat(), data.w_vector.y.toFloat(), data.w_vector.z.toFloat(), + data.currentVector.x.toFloat(), data.currentVector.y.toFloat(), data.currentVector.z.toFloat(), + data.targetVector.x.toFloat(), data.targetVector.y.toFloat(), data.targetVector.z.toFloat(), data.distance.toFloat() ) }.toTypedArray() diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt index 4435f459418..1bfdc9c3fbd 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationsConfigurable.kt @@ -27,7 +27,8 @@ open class RotationsConfigurable( BezierAngleSmoothMode(it), SigmoidAngleSmoothMode(it), ConditionalLinearAngleSmoothMode(it), - AccelerationSmoothMode(it) + AccelerationSmoothMode(it), + TensorflowSmoothMode(it), ) } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt index eb6d86c20dd..c470d1d2793 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AccelerationSmoothMode.kt @@ -97,6 +97,7 @@ class AccelerationSmoothMode(override val parent: ChoiceConfigurable<*>) : Angle } override fun limitAngleChange( + factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt index 4a6960b3521..e7ade0b09b2 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/AngleSmoothMode.kt @@ -31,6 +31,7 @@ import net.minecraft.util.math.Vec3d */ abstract class AngleSmoothMode(name: String) : Choice(name) { abstract fun limitAngleChange( + factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d? = null, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt new file mode 100644 index 00000000000..2306e704d5c --- /dev/null +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/BezierAngleSmoothMode.kt @@ -0,0 +1,80 @@ +/* + * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce) + * + * Copyright (c) 2015 - 2025 CCBlueX + * + * LiquidBounce is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LiquidBounce is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LiquidBounce. If not, see . + * + */ +package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth + +import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.utils.aiming.data.Rotation +import net.ccbluex.liquidbounce.utils.kotlin.random +import net.minecraft.entity.Entity +import net.minecraft.util.math.Vec3d +import kotlin.math.abs +import kotlin.math.min + +class BezierAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSmoothMode("Bezier") { + private val horizontalTurnSpeed by floatRange("HorizontalTurnSpeed", 180f..180f, 0.0f..180f) + private val verticalTurnSpeed by floatRange("VerticalTurnSpeed", 180f..180f, 0.0f..180f) + private val controlPoint by float("ControlPoint", 0.5f, 0.0f..1.0f) + + override fun limitAngleChange( + factorModifier: Float, + currentRotation: Rotation, + targetRotation: Rotation, + vec3d: Vec3d?, + entity: Entity? + ): Rotation { + val diff = currentRotation.rotationDeltaTo(targetRotation) + val rotationDifference = diff.length() + + val (factorH, factorV) = computeFactor(rotationDifference, horizontalTurnSpeed.random()) to + computeFactor(rotationDifference, verticalTurnSpeed.random()) + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) + + return Rotation( + currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), + currentRotation.pitch + diff.deltaPitch.coerceIn(-straightLinePitch, straightLinePitch) + ) + } + + override fun howLongToReach(currentRotation: Rotation, targetRotation: Rotation): Int { + val diff = currentRotation.rotationDeltaTo(targetRotation) + val rotationDifference = diff.length() + + val (factorH, factorV) = computeFactor(rotationDifference, horizontalTurnSpeed.random()) to + computeFactor(rotationDifference, verticalTurnSpeed.random()) + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV + return (rotationDifference / min(straightLineYaw, straightLinePitch)).toInt() + } + + private fun computeFactor(rotationDifference: Float, turnSpeed: Double): Float { + val t = (rotationDifference / 180).coerceIn(0f, 1f) + + val bezierSpeed = bezierInterpolate(0f, controlPoint, 1f, 1 - t) * turnSpeed + + return bezierSpeed.toFloat() + .coerceAtLeast(0f) + .coerceAtMost(180f) + } + + private fun bezierInterpolate(start: Float, control: Float, end: Float, t: Float): Float { + return (1 - t) * (1 - t) * start + 2 * (1 - t) * t * control + t * t * end + } +} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt index 929b6ac74e9..7a5f0640425 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/ConditionalLinearAngleSmoothMode.kt @@ -51,6 +51,7 @@ class ConditionalLinearAngleSmoothMode(override val parent: ChoiceConfigurable<* private val failIncrementV by float("FailIncrementV", 0f, 0.0f..10f) override fun limitAngleChange( + factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, @@ -70,9 +71,9 @@ class ConditionalLinearAngleSmoothMode(override val parent: ChoiceConfigurable<* crosshair, ) - val straightLineYaw = max(abs(diff.deltaYaw / rotationDifference) * factorH, + val straightLineYaw = max(abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier), minimumTurnSpeedH) - val straightLinePitch = max(abs(diff.deltaPitch / rotationDifference) * factorV, + val straightLinePitch = max(abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier), minimumTurnSpeedV) return Rotation( diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt index b700226a322..88c578ace17 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/LinearAngleSmoothMode.kt @@ -38,6 +38,7 @@ class LinearAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleS 0.0f..180f) override fun limitAngleChange( + factorModifier: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, @@ -49,8 +50,8 @@ class LinearAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleS val (factorH, factorV) = horizontalTurnSpeed.random().toFloat() to verticalTurnSpeed.random().toFloat() - val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH - val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) return Rotation( currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt new file mode 100644 index 00000000000..a3384b88b1b --- /dev/null +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/SigmoidAngleSmoothMode.kt @@ -0,0 +1,97 @@ +/* + * This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce) + * + * Copyright (c) 2015 - 2025 CCBlueX + * + * LiquidBounce is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LiquidBounce is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LiquidBounce. If not, see . + * + * + */ + +package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth + +import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.utils.aiming.data.Rotation +import net.ccbluex.liquidbounce.utils.kotlin.random +import net.minecraft.entity.Entity +import net.minecraft.util.math.Vec3d +import kotlin.math.abs +import kotlin.math.exp +import kotlin.math.min + +class SigmoidAngleSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSmoothMode("Sigmoid") { + + private val horizontalTurnSpeed by floatRange("HorizontalTurnSpeed", 180f..180f, + 0.0f..180f) + private val verticalTurnSpeed by floatRange("VerticalTurnSpeed", 180f..180f, + 0.0f..180f) + + private val steepness by float("Steepness", 10f, 0.0f..20f) + private val midpoint by float("Midpoint", 0.3f, 0.0f..1.0f) + + override fun limitAngleChange( + factorModifier: Float, + currentRotation: Rotation, + targetRotation: Rotation, + vec3d: Vec3d?, + entity: Entity? + ): Rotation { + val diff = currentRotation.rotationDeltaTo(targetRotation) + + val rotationDifference = diff.length() + + val (factorH, factorV) = + computeFactor(rotationDifference, horizontalTurnSpeed.random()) to + computeFactor(rotationDifference, verticalTurnSpeed.random()) + + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * (factorH * factorModifier) + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * (factorV * factorModifier) + + return Rotation( + currentRotation.yaw + diff.deltaYaw.coerceIn(-straightLineYaw, straightLineYaw), + currentRotation.pitch + diff.deltaPitch.coerceIn(-straightLinePitch, straightLinePitch) + ) + } + + override fun howLongToReach(currentRotation: Rotation, targetRotation: Rotation): Int { + val diff = currentRotation.rotationDeltaTo(targetRotation) + + val rotationDifference = diff.length() + + val (factorH, factorV) = + computeFactor(rotationDifference, horizontalTurnSpeed.random()) to + computeFactor(rotationDifference, verticalTurnSpeed.random()) + + val straightLineYaw = abs(diff.deltaYaw / rotationDifference) * factorH + val straightLinePitch = abs(diff.deltaPitch / rotationDifference) * factorV + + return (rotationDifference / min(straightLineYaw, straightLinePitch)).toInt() + } + + private fun computeFactor(rotationDifference: Float, turnSpeed: Double): Float { + // Scale the rotation difference to fit within a reasonable range + val scaledDifference = rotationDifference / 120f + + // Compute the sigmoid function + val sigmoid = 1 / (1 + exp((-steepness * (scaledDifference - midpoint)).toDouble())) + + // Interpolate sigmoid value to fit within the range of turnSpeed + val interpolatedSpeed = sigmoid * turnSpeed + + return interpolatedSpeed.toFloat() + .coerceAtLeast(0f) + .coerceAtMost(180f) + } + +} diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt index 7f6ea8e6d76..24b4813f650 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt @@ -49,6 +49,7 @@ class TensorflowSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSm } override fun limitAngleChange( + rotationFactor: Float, currentRotation: Rotation, targetRotation: Rotation, vec3d: Vec3d?, From 37747db7de3792f1c6b73975bacdfe13010ff40e Mon Sep 17 00:00:00 2001 From: Izuna Date: Sun, 16 Feb 2025 08:11:32 +0100 Subject: [PATCH 3/3] detekt fix --- src/main/kotlin/DataModelTrainer.kt | 4 +-- ...eSmoothMode.kt => TensorflowSmoothMode.kt} | 26 ++++++++----------- 2 files changed, 12 insertions(+), 18 deletions(-) rename src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/{TestAngleSmoothMode.kt => TensorflowSmoothMode.kt} (75%) diff --git a/src/main/kotlin/DataModelTrainer.kt b/src/main/kotlin/DataModelTrainer.kt index 87947bd09f7..3dd9218e621 100644 --- a/src/main/kotlin/DataModelTrainer.kt +++ b/src/main/kotlin/DataModelTrainer.kt @@ -125,9 +125,7 @@ fun parseJson(jsonString: String): List { fun readTrainingDataFromFolder(folderPath: String): List { val folder = File(folderPath) - if (!folder.exists() || !folder.isDirectory) { - throw IllegalArgumentException("Invalid folder path: $folderPath") - } + require(folder.exists() && folder.isDirectory) { "Invalid folder path: $folderPath" } return folder.listFiles { file -> file.isFile && file.extension == "json" } ?.flatMap { file -> diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TensorflowSmoothMode.kt similarity index 75% rename from src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt rename to src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TensorflowSmoothMode.kt index 24b4813f650..74d1f503771 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TestAngleSmoothMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/features/anglesmooth/TensorflowSmoothMode.kt @@ -1,8 +1,8 @@ package net.ccbluex.liquidbounce.utils.aiming.features.anglesmooth import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable +import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug import net.ccbluex.liquidbounce.utils.aiming.data.Rotation -import net.ccbluex.liquidbounce.utils.client.chat import net.ccbluex.liquidbounce.utils.entity.boxedDistanceTo import net.minecraft.entity.Entity import net.minecraft.util.math.Vec3d @@ -27,6 +27,7 @@ class TensorflowSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSm } // TODO: How do I combine these two models into one? + // Kotlinx DL doesn't support multiple outputs in a single model? private val yawModel: Sequential = loadModel("./models/yaw_model") private val pitchModel: Sequential = loadModel("./models/pitch_model") @@ -55,29 +56,24 @@ class TensorflowSmoothMode(override val parent: ChoiceConfigurable<*>) : AngleSm vec3d: Vec3d?, entity: Entity? ): Rotation { - /** - * floatArrayOf( - * data.c_vector.x.toFloat(), data.c_vector.y.toFloat(), data.c_vector.z.toFloat(), - * data.w_vector.x.toFloat(), data.w_vector.y.toFloat(), data.w_vector.z.toFloat(), - * data.distance.toFloat() - * ) - */ - val c_vector = currentRotation.directionVector - val w_vector = targetRotation.directionVector + val currentDirectionVector = currentRotation.directionVector + val targetDirectionVector = targetRotation.directionVector val distance = entity?.let { entity -> player.boxedDistanceTo(entity) } ?: 0.0 val predictedYaw = yawModel.predictSoftly(floatArrayOf( - c_vector.x.toFloat(), c_vector.y.toFloat(), c_vector.z.toFloat(), - w_vector.x.toFloat(), w_vector.y.toFloat(), w_vector.z.toFloat(), + currentDirectionVector.x.toFloat(), currentDirectionVector.y.toFloat(), currentDirectionVector.z.toFloat(), + targetDirectionVector.x.toFloat(), targetDirectionVector.y.toFloat(), targetDirectionVector.z.toFloat(), distance.toFloat() ))[0] val predictedPitch = pitchModel.predictSoftly(floatArrayOf( - c_vector.x.toFloat(), c_vector.y.toFloat(), c_vector.z.toFloat(), - w_vector.x.toFloat(), w_vector.y.toFloat(), w_vector.z.toFloat(), + currentDirectionVector.x.toFloat(), currentDirectionVector.y.toFloat(), currentDirectionVector.z.toFloat(), + targetDirectionVector.x.toFloat(), targetDirectionVector.y.toFloat(), targetDirectionVector.z.toFloat(), distance.toFloat() ))[0] - chat("TensorFlow -> Yaw: $predictedYaw, Pitch: $predictedPitch") + + ModuleDebug.debugParameter(this, "Yaw", predictedYaw) + ModuleDebug.debugParameter(this, "Pitch", predictedPitch) return Rotation( currentRotation.yaw + predictedYaw,