diff --git a/src/main/kotlin/codes/som/hibiscus/Hibiscus.kt b/src/main/kotlin/codes/som/hibiscus/Hibiscus.kt index 069455a..2eb7d52 100644 --- a/src/main/kotlin/codes/som/hibiscus/Hibiscus.kt +++ b/src/main/kotlin/codes/som/hibiscus/Hibiscus.kt @@ -15,6 +15,7 @@ import codes.som.hibiscus.gui.screens.AccountManagerUIScreen import codes.som.hibiscus.gui.screens.InGameClientUIScreen import codes.som.hibiscus.mixins.MixinExtMinecraftClient import codes.som.hibiscus.subsystems.accounts.AccountsSubsystem +import codes.som.hibiscus.subsystems.tps.TPSDetectionSubsystem import codes.som.hibiscus.util.command.ChatCommandListener import codes.som.hibiscus.util.input.KeybindDispatcher import codes.som.hibiscus.util.netmoving.NetworkMovingDispatcher @@ -56,6 +57,7 @@ object Hibiscus : ModInitializer { bus.register(NetworkMovingDispatcher(), EventPhase.AFTER) bus.register(ChatCommandListener()) bus.register(KeybindDispatcher()) + TPSDetectionSubsystem.setup() defaultConfig() diff --git a/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt b/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt index 18fd1a5..64365af 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt @@ -1,17 +1,20 @@ package codes.som.hibiscus.features.movement +import codes.som.hibiscus.api.event.EventPhase import codes.som.hibiscus.api.feature.Feature import codes.som.hibiscus.api.feature.FeatureCategory import codes.som.hibiscus.events.* import codes.som.hibiscus.mc import codes.som.hibiscus.mixins.MixinExtUpdatePlayerAbilitiesC2SPacket import codes.som.hibiscus.player +import codes.som.hibiscus.subsystems.tps.TPSDetectionSubsystem import codes.som.hibiscus.util.ext.requireExtension import codes.som.hibiscus.util.math.constructMovementVectorFromKeyboard import codes.som.hibiscus.world import net.minecraft.entity.MovementType import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket import net.minecraft.network.packet.c2s.play.UpdatePlayerAbilitiesC2SPacket +import net.minecraft.util.math.Vec3d import net.minecraft.util.shape.VoxelShape class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { @@ -21,10 +24,12 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { private val spoofAbilityPackets by values.bool("Spoof Outgoing Ability Packets", true) private val vanillaKickBypass by values.bool("Vanilla Kick Bypass", true) private val mode by values.enum("Mode", FlightMode.HARD) + private val speed by values.float("Speed", 1.0f, 0.01f, 50.0f) init { on(cond = { mode == FlightMode.VANILLA }) { _: PlayerTickEvent -> player.abilities.flying = true + player.abilities.flySpeed = speed * 0.05f } on(cond = { mode == FlightMode.HARD }) { event: MovePlayerEvent -> @@ -35,6 +40,8 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { constructMovementVectorFromKeyboard(player.yaw) .multiply(if (player.isSprinting) 1.5 else 0.75) .multiply(1.0, 0.75, 1.0) + .multiply(speed.toDouble()) + // TODO: Some form of acceleration event.x = movement.x event.y = movement.y @@ -43,10 +50,41 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { player.velocity = movement.multiply(0.25, 0.25, 0.25) } - on(cond = { mode == FlightMode.HARD }) { _: PlayerInputTickEvent -> + on(cond = { mode != FlightMode.VANILLA }) { _: PlayerInputTickEvent -> player.input.sneaking = false } + var lastMoveTime: Long = -1 + on(cond = { mode == FlightMode.MAXIMUM }, phase = EventPhase.AFTER) { event: MovePlayerEvent -> + if (event.movementType != MovementType.SELF) + return@on + + var tpsMultiplier = TPSDetectionSubsystem.average().coerceAtMost(1.0) + if (tpsMultiplier < 1) { + tpsMultiplier = 1 - (1 - tpsMultiplier) * 4.0 + } + + val currTime = System.currentTimeMillis() + val movement = + if (lastMoveTime == -1L || currTime - lastMoveTime >= (1000.0 / 21.0) * tpsMultiplier) { + constructMovementVectorFromKeyboard(player.yaw) + .normalize() + .multiply(speed.toDouble() * (10.0 - 1 / 8)) + .multiply(1.0, 0.5, 1.0) + } else { + Vec3d.ZERO + } + + if (movement != Vec3d.ZERO) + lastMoveTime = currTime + + event.x = movement.x + event.y = movement.y + event.z = movement.z + + player.velocity = Vec3d.ZERO + } + on(cond = { spoofAbilityPackets }) { event: SendPacketEvent -> val (packet) = event @@ -92,6 +130,7 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { override fun onDisable() { player.abilities.flying = false + player.abilities.flySpeed = 0.05f } override fun createFeatureCommand() = @@ -100,7 +139,7 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { } enum class FlightMode { - VANILLA, HARD; + VANILLA, HARD, MAXIMUM; override fun toString(): String { return name[0] + name.substring(1).lowercase() diff --git a/src/main/kotlin/codes/som/hibiscus/features/overlay/Overlay.kt b/src/main/kotlin/codes/som/hibiscus/features/overlay/Overlay.kt index be058db..e6ababc 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/overlay/Overlay.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/overlay/Overlay.kt @@ -5,6 +5,7 @@ import codes.som.hibiscus.api.feature.Feature import codes.som.hibiscus.api.feature.FeatureCategory import codes.som.hibiscus.events.PostRenderAllEvent import codes.som.hibiscus.mc +import codes.som.hibiscus.subsystems.tps.TPSDetectionSubsystem import imgui.ImGui import imgui.flag.ImGuiCol import imgui.flag.ImGuiWindowFlags @@ -12,6 +13,7 @@ import imgui.flag.ImGuiWindowFlags class Overlay : Feature("Overlay", FeatureCategory.OVERLAY) { init { val enabledFeatures by values.bool("Enabled Features", true) + val tps by values.bool("TPS", false) on { _: PostRenderAllEvent -> if (mc.world == null || mc.options.debugEnabled) @@ -27,6 +29,9 @@ class Overlay : Feature("Overlay", FeatureCategory.OVERLAY) { ImGuiWindowFlags.NoMove + ImGuiWindowFlags.NoInputs + ImGuiWindowFlags.NoDecoration ) + if (tps) + ImGui.text("TPS: " + "%.2f".format(20.0 * TPSDetectionSubsystem.average())) + if (enabledFeatures) drawEnabledFeatures() diff --git a/src/main/kotlin/codes/som/hibiscus/subsystems/tps/TPSDetectionSubsystem.kt b/src/main/kotlin/codes/som/hibiscus/subsystems/tps/TPSDetectionSubsystem.kt new file mode 100644 index 0000000..1c8a7ba --- /dev/null +++ b/src/main/kotlin/codes/som/hibiscus/subsystems/tps/TPSDetectionSubsystem.kt @@ -0,0 +1,37 @@ +package codes.som.hibiscus.subsystems.tps + +import codes.som.hibiscus.Hibiscus +import codes.som.hibiscus.events.PostRenderAllEvent +import codes.som.hibiscus.events.ReceivePacketEvent +import codes.som.hibiscus.mc +import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket + +object TPSDetectionSubsystem { + private val tpsMultipliers = mutableListOf() + private var lastSecond: Long = -1 + + fun average() = + if (tpsMultipliers.isEmpty()) 1.0 + else tpsMultipliers.sum() / tpsMultipliers.size.toDouble() + + fun setup() { + Hibiscus.bus.register { _: PostRenderAllEvent -> + if (mc.world == null) { + lastSecond = -1 + tpsMultipliers.clear() + } + } + + Hibiscus.bus.register { event: ReceivePacketEvent -> + if (event.packet is WorldTimeUpdateS2CPacket) { + val currTime = System.currentTimeMillis() + if (lastSecond != -1L) { + tpsMultipliers.add((currTime - lastSecond) / 1000.0) + if (tpsMultipliers.size > 2) + tpsMultipliers.removeAt(0) + } + lastSecond = currTime + } + } + } +}