1+ /*
2+ * Copyright 2025 Lambda
3+ *
4+ * This program is free software: you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation, either version 3 of the License, or
7+ * (at your option) any later version.
8+ *
9+ * This program is distributed in the hope that it will be useful,
10+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ * GNU General Public License for more details.
13+ *
14+ * You should have received a copy of the GNU General Public License
15+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16+ */
17+
18+ package com.lambda.module.modules.movement
19+
20+ import com.lambda.event.events.MovementEvent
21+ import com.lambda.event.events.PacketEvent
22+ import com.lambda.event.listener.SafeListener.Companion.listen
23+ import com.lambda.module.tag.ModuleTag
24+ import com.lambda.module.Module
25+ import com.lambda.util.Communication.debug
26+ import com.lambda.util.Communication.info
27+ import com.lambda.util.NamedEnum
28+ import net.minecraft.network.packet.c2s.play.UpdatePlayerAbilitiesC2SPacket
29+ import net.minecraft.network.packet.s2c.play.PlayerAbilitiesS2CPacket
30+
31+
32+ object Flight : Module(
33+ name = " Flight" ,
34+ description = " Allows you to fly" ,
35+ defaultTags = setOf(ModuleTag .MOVEMENT )
36+ ) {
37+ val mode by setting(" Mode" , Mode .CREATIVE );
38+
39+ private val speed by setting(" Speed" , 1.0 , 0.1 .. 5.0 , 0.01 )
40+
41+ // Creative
42+ private val preventDisable by setting(" Prevent Disable" , true , description = " Prevent the server from disabling the flying ability" ) { mode == Mode .CREATIVE }
43+ private val conceal by setting(" Conceal" , true , description = " Cancels outgoing player ability update packets" ) { mode == Mode .CREATIVE }
44+ private val onlyAllow by setting(" Only Allow" , false , description = " Allows you to fly just like in creative mode" ) { mode == Mode .CREATIVE }
45+
46+ data class Abilities (val flyingAllowed : Boolean , val flySpeed : Float )
47+
48+ private var preAbilities = Abilities (false , 0.15F ) // Store if server allows us to fly so we don't break flying ability after disabling
49+
50+ enum class Mode (override val displayName : String ) : NamedEnum {
51+ GROUNDSPOOF (" Ground spoof" ), // TODO: Implement
52+ CREATIVE (" Creative" ),
53+ }
54+
55+
56+ init {
57+ // Cancel packets that disable flying state/ability
58+ listen<PacketEvent .Receive .Pre > { event ->
59+ if (! preventDisable) return @listen
60+ val packet = event.packet
61+ if (packet is PlayerAbilitiesS2CPacket ) {
62+ // If the server attempts to enforce the abilities present before toggling, cancel
63+ if (packet.allowFlying() == preAbilities.flyingAllowed || packet.isFlying != isEnabled) {
64+ info(" server tried to cancel flight" )
65+ debug(packet.toString())
66+ event.cancel()
67+ }
68+ }
69+ }
70+
71+ // Prevent outgoing player ability updates because it will stand out when a survival player starts flying
72+ listen<PacketEvent .Send .Pre > { event ->
73+ if (! conceal) return @listen
74+ val packet = event.packet
75+ if (packet is UpdatePlayerAbilitiesC2SPacket ) {
76+ debug(packet.toString())
77+ event.cancel()
78+ }
79+ }
80+
81+ listen<MovementEvent .Player .Pre > { event ->
82+ when (mode) {
83+ Mode .GROUNDSPOOF -> {
84+ }
85+
86+ Mode .CREATIVE -> {
87+ player.abilities.allowFlying = true
88+ if (! onlyAllow) {
89+ player.abilities.flying = true
90+ player.abilities.flySpeed = 0.05F * speed.toFloat()
91+ }
92+ }
93+ }
94+ }
95+
96+ onEnable {
97+ when (mode) {
98+ Mode .GROUNDSPOOF -> {
99+ }
100+
101+ Mode .CREATIVE -> {
102+ preAbilities = Abilities (player.abilities.allowFlying,player.abilities.flySpeed)
103+ player.abilities.allowFlying = true ;
104+ if (! onlyAllow) player.abilities.flying = true ;
105+ }
106+ }
107+ }
108+
109+ onDisable {
110+ when (mode) {
111+ Mode .GROUNDSPOOF -> {
112+ }
113+
114+ Mode .CREATIVE -> {
115+ player.abilities.flying = false ;
116+
117+ // Set abilities back to server defaults
118+ player.abilities.allowFlying = preAbilities.flyingAllowed
119+ player.abilities.flySpeed = preAbilities.flySpeed
120+ }
121+ }
122+ }
123+ }
124+ }
0 commit comments