package anti.cheat.modules.impl.combat;
import anti.cheat.gui.settings.BooleanSetting;
import anti.cheat.gui.settings.ModeSetting;
import anti.cheat.gui.settings.NumberSetting;
import anti.cheat.modules.Category;
import anti.cheat.modules.Module;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ShieldItem;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Unique;
import java.util.Comparator;
import java.util.Random;
import java.util.stream.StreamSupport;
public class KillAura extends Module {
[USER=182640]@Unique[/USER]
private static KillAura instance;
public static KillAura getInstance() {
return instance;
}
public boolean isSpoofingRotation() {
return isEnabled() && (rotationMode.getValue().equals("Packet") || rotationMode.getValue().equals("Smooth"));
}
public float getSpoofedYaw() {
return finalYawToSend;
}
public float getSpoofedPitch() {
return finalPitchToSend;
}
protected final MinecraftClient mc = MinecraftClient.getInstance();
private final Random random = new Random();
private final NumberSetting range = new NumberSetting("Range", 0.0, 6.0, 4.2, 0.1);
private final NumberSetting fov = new NumberSetting("FOV", 0, 360, 360, 5);
private final BooleanSetting players = new BooleanSetting("Players", true);
private final BooleanSetting mobs = new BooleanSetting("Mobs", true);
private final BooleanSetting animals = new BooleanSetting("Animals", false);
private final BooleanSetting invisibles = new BooleanSetting("Invisibles", false);
private final BooleanSetting throughWalls = new BooleanSetting("ThroughWalls", false);
private final ModeSetting rotationMode = new ModeSetting("Rotation", "Smooth", "None", "Packet", "Smooth");
private final NumberSetting rotationSpeed = new NumberSetting("RotSpeed", 0.0, 25.0, 15.0, 0.5); //регулировка скорости вращения
private final NumberSetting baseRotationNoise = new NumberSetting("RotNoise", 0.0, 3.0, 0.6, 0.1); //регулировка погрешности, потом мультипоинты надо сделать
private final NumberSetting aimPointRandomness = new NumberSetting("AimVariability", 0.0, 1.0, 0.45, 0.05);
private final ModeSetting targetPrio = new ModeSetting("Priority", "Distance", "Distance", "Health", "FOV");
private final BooleanSetting onlycriticals = new BooleanSetting("Only Criticals", false); //не доделал
private final BooleanSetting requireCriticals = new BooleanSetting("RequireCriticals", false);
private final ModeSetting criticalsMode = new ModeSetting("CritMode", "Packet", "Packet", "Jump", "Hop");
private final BooleanSetting movementCorrection = new BooleanSetting("MovementCorrection", false); //не написан
[USER=1265501]@nullable[/USER]
private LivingEntity target = null;
private boolean wasBlocking = false;
private long attackDelay = 0;
private long lastAttackTime = 0;
private float serverSentYaw;
private float serverSentPitch;
private boolean isPerformingCritManeuver = false;
private long critManeuverStartTime = 0;
private static final long CRIT_MANEUVER_TIMEOUT = 200;
private static final double CRIT_PACKET_OFFSET_1 = 0.0625;
private static final double CRIT_PACKET_OFFSET_2 = 1.1E-5;
private static final double CRIT_HOP_OFFSET = 0.0626;
private float desiredYaw;
private float desiredPitch;
private float yawNoiseOffset;
private float pitchNoiseOffset;
private long lastNoiseUpdateTime;
private static final int NOISE_UPDATE_INTERVAL = 5;
public static float finalYawToSend;
public static float finalPitchToSend;
private static KeyBinding toggleKeybind;
private void calculateAttackAngles(LivingEntity target) {
Vec3d targetPos = target.getPos();
Vec3d playerPos = mc.player.getPos();
Vec3d diff = targetPos.subtract(playerPos);
finalYawToSend = (float)Math.toDegrees(Math.atan2(diff.z, diff.x)) - 90.0f;
finalPitchToSend = (float)-Math.toDegrees(Math.atan2(diff.y, Math.sqrt(diff.x * diff.x + diff.z * diff.z)));
finalYawToSend += (random.nextFloat() - 0.5f) * 5.0f;
finalPitchToSend += (random.nextFloat() - 0.5f) * 5.0f;
}
public KillAura() {
super("KillAura", Category.Combat);
instance = this;
addSetting(range, fov, players, mobs, animals, invisibles, throughWalls, rotationMode, rotationSpeed, baseRotationNoise, aimPointRandomness, targetPrio, onlycriticals, requireCriticals, criticalsMode, movementCorrection);
toggleKeybind = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.mre.killaura.toggle", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "category.mre.combat")); //пока нету бинд системы
ClientTickEvents.END_CLIENT_TICK.register(client -> {
if (toggleKeybind.wasPressed()) {
toggle();
}
if (isEnabled() && client.player != null && client.world != null && !client.player.isSpectator() && client.interactionManager != null && client.getNetworkHandler() != null) {
onTick();
} else if (!isEnabled()) {
resetState();
}
});
}
[USER=1265501]@nullable[/USER]
public LivingEntity getTarget() {
return target;
}
[USER=1367676]@override[/USER]
public void onEnable() {
resetState();
if (mc.player != null) {
serverSentYaw = mc.player.getYaw();
serverSentPitch = mc.player.getPitch();
desiredYaw = mc.player.getYaw();
desiredPitch = mc.player.getPitch();
yawNoiseOffset = 0;
pitchNoiseOffset = 0;
lastNoiseUpdateTime = 0;
}
}
[USER=1367676]@override[/USER]
public void onDisable() {
resetState();
}
private void resetState() {
target = null;
wasBlocking = false;
lastAttackTime = 0;
attackDelay = AttackDelay();
isPerformingCritManeuver = false;
critManeuverStartTime = 0;
}
[USER=1367676]@override[/USER]
public void onTick() {
if (target != null) {
calculateAttackAngles(target);
}
ClientPlayerEntity player = mc.player;
ClientWorld world = mc.world;
if (player == null || world == null || mc.interactionManager == null || mc.getNetworkHandler() == null || mc.options == null) {
resetState();
return;
}
if (!TargetCheck(player)) {
findTarget(player, world);
if (!TargetCheck(player)) {
target = null;
isPerformingCritManeuver = false;
return;
}
}
handleRotations(player, target);
Attack(player, target);
}
private void findTarget(ClientPlayerEntity player, ClientWorld world) {
this.target = StreamSupport.stream(world.getEntities().spliterator(), false)
.filter(entity -> entity instanceof LivingEntity && entity != player && !entity.isRemoved() && entity.isAlive())
.map(entity -> (LivingEntity) entity)
.filter(entity -> player.distanceTo(entity) <= range.getValue())
.filter(this::FovCheck)
.filter(entity -> invisibles.getValue() || !entity.isInvisible())
.filter(entity -> throughWalls.getValue() || VisibleCheck(player, entity))
.filter(this::TargetType)
.min(getComparator(player))
.orElse(null);
}
private boolean TargetCheck(ClientPlayerEntity player) {
return target != null && target.isAlive() && !target.isRemoved() && player.distanceTo(target) <= range.getValue() + 1.0;
}
private boolean TargetType(LivingEntity entity) {
if (entity instanceof PlayerEntity && players.getValue()) return true;
if (entity instanceof HostileEntity && mobs.getValue()) return true;
if (entity instanceof AnimalEntity && animals.getValue()) return true;
if (!(entity instanceof PlayerEntity) && !(entity instanceof HostileEntity) && animals.getValue()) return true;
return false;
}
private boolean FovCheck(Entity entity) {
if (fov.getValue() >= 360 || mc.player == null) return true;
float referenceYaw = movementCorrection.getValue() ? mc.player.getYaw() : serverSentYaw;
double angleDiff = getAngle(entity.getPos(), referenceYaw, mc.player.getPos());
return Math.abs(angleDiff) <= fov.getValue() / 2.0;
}
private boolean VisibleCheck(ClientPlayerEntity player, Entity entity) {
ClientWorld world = mc.world;
if (world == null) return false;
Vec3d eyesPos = player.getEyePos();
Vec3d targetPos = entity.getPos().add(0, entity.getHeight() * 0.7, 0);
HitResult result = world.raycast(new RaycastContext(eyesPos, targetPos, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, player));
if (result.getType() == HitResult.Type.MISS) return true;
if (result.getType() == HitResult.Type.ENTITY) {
return ((EntityHitResult) result).getEntity().equals(entity);
} else if (result.getType() == HitResult.Type.BLOCK) {
return result.getPos().distanceTo(targetPos) < 1.5;
}
return false;
}
private Comparator<LivingEntity> getComparator(ClientPlayerEntity player) {
return switch (targetPrio.getValue()) {
case "Health" -> Comparator.<LivingEntity>comparingDouble(LivingEntity::getHealth)
.thenComparingDouble(e -> player.squaredDistanceTo(e));
case "FOV" -> Comparator.<LivingEntity>comparingDouble(e -> Math.abs(getAngle(e.getPos(), player.getYaw(), player.getPos())))
.thenComparingDouble(e -> player.squaredDistanceTo(e));
default ->
Comparator.comparingDouble(e -> player.squaredDistanceTo(e));
};
}
private double getAngle(Vec3d targetPos, float referenceYaw, Vec3d viewerPos) {
double vecX = targetPos.x - viewerPos.x;
double vecZ = targetPos.z - viewerPos.z;
double angleToTarget = Math.toDegrees(Math.atan2(vecZ, vecX)) - 90.0f;
return MathHelper.wrapDegrees(angleToTarget - referenceYaw);
}
private void handleRotations(ClientPlayerEntity player, LivingEntity target) {
if (rotationMode.getValue().equals("None") || target == null) {
return;
}
float[] targetRotations = Target(player, target);
float targetYaw = targetRotations[0];
float targetPitch = targetRotations[1];
desiredYaw = smoothRotation(desiredYaw, targetYaw, 180f);
desiredPitch = smoothRotation(desiredPitch, targetPitch, 90f);
float yawDelta = Math.abs(MathHelper.wrapDegrees(desiredYaw - serverSentYaw));
float pitchDelta = Math.abs(MathHelper.wrapDegrees(desiredPitch - serverSentPitch));
float baseSpeed = (float) rotationSpeed.getValue();
float speedYaw = baseSpeed * (0.5f + yawDelta / 180f);
float speedPitch = baseSpeed * (0.5f + pitchDelta / 90f);
serverSentYaw = smoothRotation(serverSentYaw, desiredYaw, speedYaw);
serverSentPitch = smoothRotation(serverSentPitch, desiredPitch, speedPitch);
serverSentPitch = MathHelper.clamp(serverSentPitch, -90.0f, 90.0f);
long worldTime = mc.world.getTime();
if (worldTime - lastNoiseUpdateTime >= NOISE_UPDATE_INTERVAL) {
float noiseAmount = (float) baseRotationNoise.getValue();
yawNoiseOffset = (random.nextFloat() - 0.5f) * noiseAmount * 2.0f;
pitchNoiseOffset = (random.nextFloat() - 0.5f) * noiseAmount * 2.0f;
lastNoiseUpdateTime = worldTime;
}
finalYawToSend = serverSentYaw + yawNoiseOffset;
finalPitchToSend = MathHelper.clamp(serverSentPitch + pitchNoiseOffset, -90f, 90f);
}
private float[] Target(ClientPlayerEntity player, LivingEntity entity) {
Vec3d eyesPos = player.getEyePos();
double aimVariability = aimPointRandomness.getValue();
double randX = (random.nextDouble() - 0.5) * aimVariability * 0.7;
double randY = (random.nextDouble() - 0.5) * aimVariability * 1.3;
double randZ = (random.nextDouble() - 0.5) * aimVariability * 0.7;
double targetX = entity.getX() + randX;
double targetY = entity.getEyeY() - 0.25 + randY;
double targetZ = entity.getZ() + randZ;
Vec3d targetPos = new Vec3d(targetX, targetY, targetZ);
double diffX = targetPos.x - eyesPos.x;
double diffY = targetPos.y - eyesPos.y;
double diffZ = targetPos.z - eyesPos.z;
double distanceHorizontal = Math.sqrt(diffX * diffX + diffZ * diffZ);
float yaw = (float) Math.toDegrees(Math.atan2(diffZ, diffX)) - 90.0f;
float pitch = (float) -Math.toDegrees(Math.atan2(diffY, distanceHorizontal));
yaw = MathHelper.wrapDegrees(yaw);
pitch = MathHelper.clamp(pitch, -90.0f, 90.0f);
return new float[]{yaw, pitch};
}
private float smoothRotation(float current, float target, float maxSpeed) {
float delta = MathHelper.wrapDegrees(target - current);
float acceleration = MathHelper.clamp(Math.abs(delta) / 45f, 0.2f, 1f);
float step = MathHelper.clamp(delta, -maxSpeed, maxSpeed) * acceleration;
return MathHelper.wrapDegrees(current + step);
}
private void Attack(ClientPlayerEntity player, [USER=1265501]@nullable[/USER] LivingEntity currentTarget) {
if (currentTarget == null || mc.interactionManager == null || mc.getNetworkHandler() == null || player == null) return;
if (player.getAttackCooldownProgress(0.5f) < 0.9f || player.isBlocking()) {
return;
}
long currentTime = System.currentTimeMillis();
if (currentTime - lastAttackTime < attackDelay) {
return;
}
if (player.getAttackCooldownProgress(0.5f) < 0.90f) {
if (isPerformingCritManeuver) {
isPerformingCritManeuver = false;
critManeuverStartTime = 0;
}
return;
}
boolean canCrit = false;
boolean needsToCrit = onlycriticals.getValue() || requireCriticals.getValue();
if (needsToCrit) {
boolean physicallyAbleToCrit = canAttemptCritical(player);
if (isPerformingCritManeuver) {
if (currentTime - critManeuverStartTime > CRIT_MANEUVER_TIMEOUT) {
isPerformingCritManeuver = false;
} else {
canCrit = isCritStateMet(player);
if (!canCrit) return;
}
} else if (physicallyAbleToCrit) {
if (!player.isOnGround() || player.isSprinting() || player.isSneaking()) {
canCrit = true;
} else {
Ctiricals(player);
isPerformingCritManeuver = true;
critManeuverStartTime = currentTime;
return;
}
} else if (onlycriticals.getValue()) {
return;
}
}
if (wasBlocking && isHoldingShield(player)) {
return;
}
boolean wasSprinting = player.isSprinting();
if (wasSprinting) {
player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.STOP_SPRINTING));
}
mc.interactionManager.attackEntity(player, currentTarget);
player.swingHand(Hand.MAIN_HAND);
lastAttackTime = currentTime;
attackDelay = AttackDelay();
if (wasSprinting && Sprint(player)) {
player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.START_SPRINTING));
}
isPerformingCritManeuver = false;
critManeuverStartTime = 0;
}
private boolean canAttemptCritical(ClientPlayerEntity player) {
if (player.isSubmergedInWater() || player.isInLava() || player.isClimbing() ||
player.hasStatusEffect(StatusEffects.BLINDNESS) || player.hasVehicle() ||
player.isSneaking()) {
return false;
}
if (!player.isOnGround()) {
double verticalVelocity = player.getVelocity().y;
if (verticalVelocity < 0) {
double fallSpeed = Math.abs(verticalVelocity);
return fallSpeed >= 0.0625 && fallSpeed <= 0.0627;
}
return false;
}
if (player.isOnGround()) {
Box headBox = player.getBoundingBox().offset(0, player.getHeight() * 0.5, 0).expand(0.1, 0.1, 0.1);
boolean clearAbove = mc.world != null && !mc.world.getBlockCollisions(player, headBox).iterator().hasNext();
return clearAbove && player.fallDistance <= 0.0f && (!onlycriticals.getValue() || player.isSprinting());
}
return false;
}
private boolean isCritStateMet(ClientPlayerEntity player) {
if (!requireCriticals.getValue()) return true;
if (!player.isOnGround() && !player.isClimbing() && !player.isTouchingWater() &&
!player.hasStatusEffect(StatusEffects.BLINDNESS) && !player.hasVehicle() &&
!player.isSubmergedInWater() && !player.isInLava() && !player.isSneaking()) {
double verticalVelocity = player.getVelocity().y;
if (verticalVelocity < 0) {
double fallSpeed = Math.abs(verticalVelocity);
return fallSpeed >= 0.0625 && fallSpeed <= 0.0627;
}
}
return false;
}
private long AttackDelay() {
if (mc.player == null || mc.player.getMainHandStack().isEmpty()) {
return 250L;
}
float attackSpeed = mc.player.getAttackCooldownProgressPerTick();
if (attackSpeed <= 0) attackSpeed = 4.0f;
float baseDelay = 20.0f / attackSpeed;
float randomization = (float) (random.nextFloat() * 2.0f - 1.0f);
return (long) ((baseDelay + randomization) * 50);
}
private void Ctiricals(ClientPlayerEntity player) {
if (mc.getNetworkHandler() == null) return;
double x = player.getX();
double y = player.getY();
double z = player.getZ();
switch (criticalsMode.getValue()) {
case "Jump":
player.jump();
break;
case "Hop":
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y + CRIT_HOP_OFFSET, z, false, false));
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, false, false));
break;
case "Packet":
default:
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y + CRIT_PACKET_OFFSET_1, z, false, false));
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, false, false));
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y + CRIT_PACKET_OFFSET_2, z, false, false));
mc.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.PositionAndOnGround(x, y, z, false, false));
break;
}
}
private boolean isHoldingShield(ClientPlayerEntity player) {
if (player == null) return false;
return player.getMainHandStack().getItem() instanceof ShieldItem ||
player.getOffHandStack().getItem() instanceof ShieldItem;
}
private boolean Sprint(ClientPlayerEntity player) {
return !player.isSprinting()
&& !player.isUsingItem()
&& !player.isSneaking()
&& !player.isSubmergedInWater()
&& !player.hasStatusEffect(StatusEffects.BLINDNESS)
&& player.getHungerManager().getFoodLevel() > 6;
}
}