Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Flight #381

Merged
merged 2 commits into from
Dec 1, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 209 additions & 48 deletions src/main/kotlin/com/lambda/client/module/modules/movement/Flight.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package com.lambda.client.module.modules.movement
import com.lambda.client.event.Phase
import com.lambda.client.event.events.OnUpdateWalkingPlayerEvent
import com.lambda.client.event.events.PacketEvent
import com.lambda.client.event.events.PlayerTravelEvent
import com.lambda.client.event.events.PlayerMoveEvent
import com.lambda.client.event.listener.listener
import com.lambda.client.manager.managers.PacketManager
import com.lambda.client.manager.managers.PlayerPacketManager.sendPlayerPacket
import com.lambda.client.mixin.extension.playerPosLookPitch
import com.lambda.client.mixin.extension.playerPosLookYaw
Expand All @@ -14,96 +13,228 @@ import com.lambda.client.module.Module
import com.lambda.client.util.MovementUtils
import com.lambda.client.util.MovementUtils.calcMoveYaw
import com.lambda.client.util.threads.runSafe
import com.lambda.client.util.threads.runSafeR
import com.lambda.client.util.threads.safeListener
import net.minecraft.network.play.client.CPacketConfirmTeleport
import net.minecraft.network.play.client.CPacketPlayer
import net.minecraft.network.play.server.SPacketCloseWindow
import net.minecraft.network.play.server.SPacketPlayerPosLook
import net.minecraft.util.math.Vec3d
import kotlin.math.cos
import kotlin.math.floor
import kotlin.math.hypot
import kotlin.math.sin


object Flight : Module(
name = "Flight",
description = "Makes the player fly",
category = Category.MOVEMENT,
modulePriority = 500
) {
// non packet
private val mode by setting("Mode", FlightMode.PACKET)
private val speed by setting("Speed", 1.0f, 0.0f..10.0f, 0.1f)
private val glideSpeed by setting("Glide Speed", 0.05, 0.0..0.3, 0.001)
private val packetMode by setting("Packet Mode", PacketMode.NEGATIVE, { mode == FlightMode.PACKET })
private val upSpeed by setting("Up Speed", 0.0622, 0.0..0.3, 0.001, { mode == FlightMode.PACKET })
private val speed by setting("Speed", 1.0f, 0f..10f, 0.1f, { mode != FlightMode.PACKET })
private val glideSpeed by setting("Glide Speed", 0.05, 0.0..0.3, 0.001, { mode != FlightMode.PACKET })

// packet
private val packetMode by setting("Packet Mode", PacketMode.FAST, { mode == FlightMode.PACKET })
private val bounds by setting("Packet Type", PacketType.NEGATIVE, { mode == FlightMode.PACKET })
private val factor by setting("Bypass Factor", 1f, 0f..10f, .1f, { mode == FlightMode.PACKET })
private val concealFactor by setting("Conceal Factor", 2f, 0f..10f, .1f, { mode == FlightMode.PACKET })
private val conceal by setting("Conceal", false, { mode == FlightMode.PACKET })
private val antiKick by setting("Anti Kick", true, { mode == FlightMode.PACKET })
private val antiKickSpeed by setting("Anti Kick Speed", 0.0622, 0.0..0.3, 0.001, { mode == FlightMode.PACKET && antiKick })
private val antiKickDelay by setting("Anti Kick Delay", 14, 0..100, 1, { mode == FlightMode.PACKET && antiKick }, unit = " ticks")
private val hShrinkAmount by setting("Horizontal Shrink Amount", 4.0, 1.0..10.0, 0.1, { mode == FlightMode.PACKET })
private val vShrinkAmount by setting("Vertical Shrink Amount", 2.70, 1.0..10.0, 0.1, { mode == FlightMode.PACKET })

private enum class FlightMode {
PACKET, VANILLA, STATIC
}

private enum class PacketType {
POSITIVE, NEGATIVE, STRICT
}

private enum class PacketMode {
POSITIVE, NEGATIVE
FAST, SETBACK
}

private const val BASE_SPEED = .2873
private const val CONCEAL_SPEED = .0624
private const val SQRT_TWO_OVER_TWO = .707106781
private const val ANTIKICK_AMOUNT = .03125

private val history = HashMap<Int, Vec3d>()
private val filter = ArrayList<CPacketPlayer.Position>()
private var tpID = -1
private var ticksEnabled = 0

init {
onDisable {
runSafe {
tpID = -1
ticksEnabled = 0
player.noClip = false

player.capabilities?.apply {
isFlying = false
flySpeed = 0.05f
}
}
}

safeListener<PlayerTravelEvent> {
onEnable {
runSafeR {
val position = CPacketPlayer.Position(.0, .0, .0, true)
filter.add(position)
connection.sendPacket(position)
} ?: disable()
}

safeListener<PlayerMoveEvent> {
when (mode) {
// uses the same concepts as https://gist.github.com/Doogie13/aa04c6a8eb496c1afdb9c675e2ebd91c
// completely written from scratch, however
FlightMode.PACKET -> {
it.cancel()
player.noClip = true

player.motionY = if (mc.gameSettings.keyBindJump.isKeyDown xor mc.gameSettings.keyBindSneak.isKeyDown) {
if (mc.gameSettings.keyBindJump.isKeyDown) {
if (player.ticksExisted % antiKickDelay == 0 && antiKick) {
-antiKickSpeed / vShrinkAmount
} else {
upSpeed / vShrinkAmount
}
} else (-upSpeed / vShrinkAmount)
} else {
if (MovementUtils.isInputting) {
val yaw = calcMoveYaw()
player.motionX = (-sin(yaw) * 0.2f * speed) / hShrinkAmount
player.motionZ = (cos(yaw) * 0.2f * speed) / hShrinkAmount
}
-glideSpeed / vShrinkAmount
// region Motion
val concealing = world.collidesWithAnyBlock(player.entityBoundingBox) || conceal
var motionY: Double
var up = 0

// we must use else if to allow phasing
if (mc.gameSettings.keyBindJump.isKeyDown)
up++
else if (mc.gameSettings.keyBindSneak.isKeyDown)
up--

motionY = if (up == 0)
.0
else
CONCEAL_SPEED * up.toDouble()

var motionXZ: Double = if (!MovementUtils.isInputting)
.0
else if (concealing)
CONCEAL_SPEED
else
BASE_SPEED

if (motionY != .0 && motionXZ == BASE_SPEED)
motionY = .0

if (motionXZ == CONCEAL_SPEED && motionY == CONCEAL_SPEED) {
motionXZ *= SQRT_TWO_OVER_TWO
motionY *= SQRT_TWO_OVER_TWO
}

val posX = player.posX + (player.motionX * hShrinkAmount)
val posY = player.posY + (player.motionY * vShrinkAmount)
val posZ = player.posZ + (player.motionZ * hShrinkAmount)
//endregion

//region packets

val calcFactor =
if (hypot(motionXZ, motionY) < .0625)
concealFactor
else
factor

var factorInt = floor(calcFactor).toInt()
val diff = calcFactor - factorInt

val invalidPacketOffset = when (packetMode) {
PacketMode.POSITIVE -> 1000
PacketMode.NEGATIVE -> -1000
if (++ticksEnabled % 10 < diff * 10)
factorInt++

if (factorInt == 0) {
player.setVelocity(.0, .0, .0)
return@safeListener
}

connection.sendPacket(CPacketPlayer.Position(posX, posY, posZ, false))
connection.sendPacket(CPacketPlayer.Position(posX, player.posY + invalidPacketOffset, posZ, false))
if (PacketManager.lastTeleportId != -1) {
connection.sendPacket(CPacketConfirmTeleport(PacketManager.lastTeleportId++))
if (motionXZ == .0 && motionY == .0)
factorInt = 1

val yaw = calcMoveYaw()

val baseX = -sin(yaw) * motionXZ
val baseY = motionY
val baseZ = cos(yaw) * motionXZ

var currentX = baseX
var currentY = if (antiKick && ticksEnabled % 10 == 0) -ANTIKICK_AMOUNT else baseY
var currentZ = baseZ

for (i in 1..factorInt) {
// should never happen
if (i > 10)
break

val moveVec = Vec3d(currentX, currentY, currentZ)

var yOffset: Double

//region bounds
when (bounds) {
PacketType.STRICT -> {
var random = (Math.random() * 256) + 256

(random + player.posY > (if (player.dimension == -1) 127 else 255))
random *= -1

yOffset = random
}
PacketType.POSITIVE -> {
yOffset = 1337.0
}
PacketType.NEGATIVE -> {
yOffset = -1337.0
}
}
//endregion

//region sending

val boundsPacket = CPacketPlayer.Position(player.posX + moveVec.x, player.posY + moveVec.y + yOffset, player.posZ + moveVec.z, true)
val movePacket = CPacketPlayer.Position(player.posX + moveVec.x, player.posY + moveVec.y, player.posZ + moveVec.z, true)

filter.add(movePacket)
filter.add(boundsPacket)

connection.sendPacket(movePacket)
connection.sendPacket(boundsPacket)

history[++tpID] = moveVec.add(player.positionVector)
connection.sendPacket(CPacketConfirmTeleport(tpID))

currentX += baseX
currentY += baseY
currentZ += baseZ

//endregion

}

//endregion

if (packetMode == PacketMode.FAST)
player.setVelocity(currentX - baseX, currentY - baseY, currentZ - baseZ)
else
player.setVelocity(.0, .0, .0)

}
FlightMode.STATIC -> {
player.capabilities.isFlying = true
player.capabilities.flySpeed = speed
var up = 0

if (mc.gameSettings.keyBindJump.isKeyDown) up++

if (mc.gameSettings.keyBindSneak.isKeyDown) up--

player.motionX = 0.0
player.motionY = -glideSpeed
player.motionZ = 0.0
player.motionY = if (up == 0) -glideSpeed else speed * up.toDouble()

if (!MovementUtils.isInputting)
return@safeListener

val yaw = calcMoveYaw()
player.motionX -= sin(yaw) * speed
player.motionZ += cos(yaw) * speed

if (mc.gameSettings.keyBindJump.isKeyDown) player.motionY += speed / 2.0f
if (mc.gameSettings.keyBindSneak.isKeyDown) player.motionY -= speed / 2.0f
}
FlightMode.VANILLA -> {
player.capabilities.isFlying = true
Expand All @@ -125,15 +256,45 @@ object Flight : Module(

safeListener<PacketEvent.Receive> {
if (mode != FlightMode.PACKET) return@safeListener
when (it.packet) {

when (val packet = it.packet) {
is SPacketPlayerPosLook -> {
it.packet.playerPosLookYaw = player.rotationYaw
it.packet.playerPosLookPitch = player.rotationPitch
val id = packet.teleportId

if (history.containsKey(packet.teleportId) && tpID != -1) {
history[id]?.let { vec ->
if (vec.x == packet.x && vec.y == packet.y && vec.z == packet.z) {
if (packetMode != PacketMode.SETBACK)
it.cancel()

history.remove(id)
player.connection.sendPacket(CPacketConfirmTeleport(id))
return@safeListener
}
}
}

packet.playerPosLookYaw = player.rotationYaw
packet.playerPosLookPitch = player.rotationPitch

player.connection.sendPacket(CPacketConfirmTeleport(id))

tpID = id
}
is SPacketCloseWindow -> {
it.cancel()
}
}
}

safeListener<PacketEvent.Send> {
if (mode != FlightMode.PACKET || it.packet !is CPacketPlayer) return@safeListener

if (!filter.contains(it.packet))
it.cancel()
else
filter.remove(it.packet)

}
}
}