Skip to content

Commit

Permalink
Refactor anti speed and tune anti KillAura
Browse files Browse the repository at this point in the history
  • Loading branch information
yogwoggf committed Apr 25, 2024
1 parent 0f25ed0 commit 37cba66
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 56 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ loader_version=0.15.9
fabric_kotlin_version=1.10.19+kotlin.1.9.23
access_widener=puffy-anti-exploit.accesswidener
# Mod Properties
mod_version=0.2.5
mod_version=0.2.6
maven_group=com.puffy
archives_base_name=puffy-anti-exploit
# Dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import net.minecraft.entity.Entity
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket
import net.minecraft.server.network.ServerPlayerEntity

const val MAXIMUM_SUSPICIOUS_HITS_IN_PERIOD = 4
const val MAXIMUM_SUSPICIOUS_HITS_IN_PERIOD = 6
const val PERIOD_TIME_IN_TICKS = 150
const val AIM_DEGREE_TOLERANCE = 35
const val AIM_DEGREE_TOLERANCE = 45

const val MAXIMUM_DISTANCE_METERS = 6
private const val MITIGATION_NAME = "KillAura"
Expand Down
61 changes: 9 additions & 52 deletions src/main/kotlin/com/puffy/mitigations/AntiSpeedMitigation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ package com.puffy.mitigations
import com.puffy.events.DetectionEventEmitter
import com.puffy.events.DetectionInfo
import com.puffy.events.PacketEventEmitter
import com.puffy.mitigations.antispeed.MagnitudeWeighter
import com.puffy.util.trimToLength
import kotlin.math.abs
import kotlin.math.sqrt
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents.EndTick
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket
import net.minecraft.server.network.ServerPlayerEntity

const val SLIDING_WINDOW_LENGTH_TICKS = 20
const val MAXIMUM_AVERAGE_MAGNITUDE = 0.95
const val MAX_FALLING_Y_DIFFERENCE = -0.5
const val MAX_ASCENDING_Y_DIFFERENCE = 0.2
const val MAXIMUM_SUSPICIOUS_MAGNITUDE_TICKS = 25

// Used if minecraft reports a XYZ before the player loads (usually garbage)
Expand Down Expand Up @@ -50,19 +49,18 @@ class AntiSpeedMitigation(val player: ServerPlayerEntity) {
)
}

private fun isSpeedHacking(): Boolean {
return suspiciousMagnitudeTicks > MAXIMUM_SUSPICIOUS_MAGNITUDE_TICKS
}
private fun isSpeedHacking(): Boolean =
suspiciousMagnitudeTicks > MAXIMUM_SUSPICIOUS_MAGNITUDE_TICKS

private fun updateSuspiciousTicksCount() {
if (calculateAverageMagnitude() >= MAXIMUM_AVERAGE_MAGNITUDE) {
if (getAverageMagnitude() >= MAXIMUM_AVERAGE_MAGNITUDE) {
suspiciousMagnitudeTicks++
} else {
suspiciousMagnitudeTicks = 0
}
}

private fun calculateAverageMagnitude(): Double {
private fun getAverageMagnitude(): Double {
if (movementMagnitudes.isEmpty()) {
return 0.0
}
Expand All @@ -76,9 +74,7 @@ class AntiSpeedMitigation(val player: ServerPlayerEntity) {
return
}

if (movementMagnitudes.count() >= SLIDING_WINDOW_LENGTH_TICKS) {
movementMagnitudes.removeAt(0)
}
movementMagnitudes.trimToLength(SLIDING_WINDOW_LENGTH_TICKS)
movementMagnitudes.add(magnitude)
}

Expand All @@ -87,47 +83,8 @@ class AntiSpeedMitigation(val player: ServerPlayerEntity) {
val yDiff = player.y - lastY
val zDiff = player.z - lastZ

return sqrt(abs(xDiff) * abs(xDiff) + abs(yDiff) * abs(yDiff) + abs(zDiff) * abs(zDiff)) *
getPlayerSpecificWeight()
}

/**
* Returns a weight to weight the final magnitude. Allows for normal behaviors to be discarded
* earlier in the system, such as boat-ice speed and falling
*/
private fun getPlayerSpecificWeight(): Double {
var weight = 1.0

if (player.isFallFlying) {
weight *= 0.20
}

if (player.y - lastY < MAX_FALLING_Y_DIFFERENCE) {
weight *= 0.55 // Helpful for reducing false positive when falling
}

// However, to combat elytra fly + other antics with fall-flight cheats we can *increase*
// sensitivity when someone is oddly levitating in fall flight.
if (player.isFallFlying && player.y - lastY > MAX_ASCENDING_Y_DIFFERENCE) {
weight *= 6
}

if (player.isCreative) {
weight *= 0
}

if (player.abilities.flying || player.abilities.allowFlying) {
// Friction is not considered during flight, so players can accidentally trigger this
// mitigation.
weight *= 0.25
}

if (player.velocity.length() > SERVER_VELOCITY_THRESHOLD) {
// Players cannot affect their own velocity, only where they are supposed to move
weight *= 0.25
}

return weight
val magnitude = abs(xDiff) * abs(xDiff) + abs(yDiff) * abs(yDiff) + abs(zDiff) * abs(zDiff)
return MagnitudeWeighter.getWeightedMagnitude(magnitude, player, lastY)
}

private fun updateLastPositionWithCurrentPosition() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.puffy.mitigations.antispeed

import java.util.function.BiPredicate
import net.minecraft.server.network.ServerPlayerEntity
import org.slf4j.LoggerFactory

data class Weight(
val title: String,
val multiplier: Double,
val predicate: BiPredicate<ServerPlayerEntity, Double>
)

const val MAX_FALLING_Y_DIFFERENCE = -0.5
const val MAX_ASCENDING_Y_DIFFERENCE = 0.2
const val SERVER_VELOCITY_THRESHOLD = 3

object MagnitudeWeighter {
private val logger = LoggerFactory.getLogger("puffy-anti-exploit")

private val weights =
listOf(
Weight("Elytra Bias", 0.20) { player, _ -> player.isFallFlying },
Weight("Falling Bias", 0.55) { player, lastY ->
player.y - lastY < MAX_FALLING_Y_DIFFERENCE
},
Weight("Elytra Flyhack Bias", 6.0) { player, lastY ->
player.isFallFlying && player.y - lastY > MAX_ASCENDING_Y_DIFFERENCE
},
Weight("Creative Mode Bias", 0.0) { player, _ -> player.isCreative },
Weight("Server-permitted Flight Bias", 0.25) { player, _ ->
player.abilities.flying || player.abilities.allowFlying
},
Weight("Server-permitted Velocity Bias", 0.25) { player, _ ->
player.velocity.length() > SERVER_VELOCITY_THRESHOLD
}
)

private fun getActiveWeightsForPlayer(player: ServerPlayerEntity, lastY: Double) =
weights.filter { weight -> weight.predicate.test(player, lastY) }

private fun getTotalWeightedMultiplier(weights: List<Weight>) =
weights.fold(1.0) { acc, weight -> weight.multiplier * acc }

fun getWeightedMagnitude(
initialMagnitude: Double,
player: ServerPlayerEntity,
lastY: Double
): Double {
val activeWeights = getActiveWeightsForPlayer(player, lastY)

activeWeights.forEach { weight ->
logger.debug("Weight '${weight.title}' is active for player ${player.name.string}")
}

return initialMagnitude * getTotalWeightedMultiplier(activeWeights)
}
}
7 changes: 7 additions & 0 deletions src/main/kotlin/com/puffy/util/TrimToLength.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.puffy.util

fun <T> MutableList<T>.trimToLength(length: Int) {
if (this.count() >= length) {
this.removeAt(0)
}
}
2 changes: 1 addition & 1 deletion src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"id": "puffy-anti-exploit",
"version": "0.2.5",
"version": "0.2.6",
"name": "puffy-anti-exploit",
"description": "A server-side anti exploit which aims to reduce the possible amount of advantages a player can obtain with a hacked client. This mod does not attempt to ban such players, it only aims to fix certain parts of the server and gently counter these players.",
"authors": [
Expand Down

0 comments on commit 37cba66

Please sign in to comment.