package test.anticheatsimulator;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
public class RotationSimulator {
private final Minecraft mc = Minecraft.getInstance();
private final Random random = new Random();
// Configuration parameters
private float maxRotationSpeed = 30.0f;
private double targetRange = 4.0d;
private boolean smoothRotation = true;
private float randomizationFactor = 0.3f;
// Last rotation values
private float lastYaw;
private float lastPitch;
public void processRotation() {
if (mc.player == null || !shouldActivate()) return;
// Find potential target
Entity target = findTarget();
if (target == null) return;
// Calculate ideal rotation to target
float[] rotations = calculateRotation(target);
// Apply modifications to appear legitimate
float[] modifiedRotations = applyLegitimateModifications(rotations);
// Apply the rotation
applyRotation(modifiedRotations[0], modifiedRotations[1]);
}
private boolean shouldActivate() {
// Add activation conditions here
return mc.player.isSprinting() && !mc.player.isRiding();
}
private Entity findTarget() {
List<Entity> entities = mc.level.entitiesForRendering()
.stream()
.filter(this::isValidTarget)
.sorted(Comparator.comparing(entity ->
mc.player.distanceToSqr(entity)))
.collect(Collectors.toList());
return entities.isEmpty() ? null : entities.get(0);
}
private boolean isValidTarget(Entity entity) {
// Implement target validation logic
return entity != mc.player &&
mc.player.distanceTo(entity) <= targetRange &&
entity.isAlive();
}
private float[] calculateRotation(Entity target) {
Vector3d playerPos = mc.player.getEyePosition(1.0f);
Vector3d targetPos = target.position().add(0, target.getBbHeight() * 0.5, 0);
double diffX = targetPos.x - playerPos.x;
double diffY = targetPos.y - playerPos.y;
double diffZ = targetPos.z - playerPos.z;
double dist = 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, dist));
return new float[]{yaw, pitch};
}
private float[] applyLegitimateModifications(float[] rotations) {
// Implement humanization logic
float targetYaw = rotations[0];
float targetPitch = rotations[1];
// Add small, natural-looking randomization
if (randomizationFactor > 0) {
targetYaw += (random.nextFloat() - 0.5f) * randomizationFactor;
targetPitch += (random.nextFloat() - 0.5f) * randomizationFactor;
}
// Enforce rotation speed limits to appear legitimate
if (smoothRotation) {
targetYaw = limitRotationChange(lastYaw, targetYaw, maxRotationSpeed);
targetPitch = limitRotationChange(lastPitch, targetPitch, maxRotationSpeed);
}
// Handle modulo 360 detection (prevent large jumps that would trigger AimModulo360)
targetYaw = handleModulo360(lastYaw, targetYaw);
// Avoid duplicate rotations (prevent AimDuplicateLook detection)
if (Math.abs(targetYaw - lastYaw) < 0.1f && Math.abs(targetPitch - lastPitch) < 0.1f) {
targetYaw += random.nextFloat() * 0.1f;
}
// Store for next tick
lastYaw = targetYaw;
lastPitch = targetPitch;
return new float[]{targetYaw, targetPitch};
}
private float limitRotationChange(float current, float target, float maxChange) {
float deltaYaw = MathHelper.wrapDegrees(target - current);
if (deltaYaw > maxChange) {
deltaYaw = maxChange;
} else if (deltaYaw < -maxChange) {
deltaYaw = -maxChange;
}
return current + deltaYaw;
}
private float handleModulo360(float current, float target) {
// Avoid rotation changes that would trigger modulo 360 detection
float delta = MathHelper.wrapDegrees(target - current);
// Ensure we don't make suspiciously large jumps
if (Math.abs(delta) > 320) {
// Instead of making a large jump, make a smaller one in the opposite direction
return current - (delta > 0 ? 30 : -30);
}
return current + delta;
}
private void applyRotation(float yaw, float pitch) {
// Apply the rotation - implementation would depend on the specific MCP version
// This is where you'd actually update the player's rotation
}
// Only use when needed, to avoid sprint patterns that anti-cheat might detect
private void handleSprint() {
if (mc.player.isSprinting()) {
// Occasionally reset sprint to avoid patterns
if (random.nextInt(100) < 5) {
mc.player.setSprinting(false);
// Re-enable after a short delay
}
}
}
}