Skip to content

Commit be3eb28

Browse files
Improved how freecam works, split client and server code, cleaned code, etc
1 parent 9192213 commit be3eb28

14 files changed

Lines changed: 201 additions & 89 deletions

File tree

build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ dependencies {
9090
// Helper library
9191
// If you do not need Halplibe you can comment this line out or delete this line
9292
modImplementation("turniplabs:halplibe:${project.halplibe_version}")
93-
9493
modImplementation("turniplabs:modmenu-bta:${project.mod_menu_version}")
94+
modImplementation("com.github.Apollointhehouse:Raywire:$raywire_version")
9595

9696
implementation "org.slf4j:slf4j-api:1.8.0-beta4"
9797
implementation "org.apache.logging.log4j:log4j-slf4j18-impl:2.16.0"
@@ -121,8 +121,6 @@ dependencies {
121121
implementation("org.lwjgl:lwjgl-opengl:$lwjglVersion")
122122
implementation("org.lwjgl:lwjgl-stb:$lwjglVersion")
123123

124-
modImplementation("com.github.Apollointhehouse:Raywire:1.0.0")
125-
126124
modImplementation("net.fabricmc:fabric-language-kotlin:${project.flk_version}+kotlin.${project.kotlin_version}") {
127125
exclude(group: "net.fabricmc", module: "fabric-loader")
128126
}

gradle.properties

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ loader_version=0.15.6-bta.7
1010
# Other Mods
1111
mod_menu_version=3.0.0
1212
halplibe_version=5.2.4
13+
raywire_version=1.0.0
1314

1415
# Fabric Language Kotlin
1516
flk_version=1.11.0
1617
kotlin_version=2.0.0
1718

1819
# Mod
1920
mod_version=1.0.0
20-
mod_group=turniplabs
21-
mod_name=examplemod
21+
mod_group=me.apollointhehouse
22+
mod_name=Freecam

src/main/java/me/apollointhehouse/mixin/GameSettingsMixin.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package me.apollointhehouse.mixin;
22

33
import me.apollointhehouse.options.FreecamOptions;
4-
import net.minecraft.client.gui.options.components.BooleanOptionComponent;
54
import net.minecraft.client.input.InputDevice;
65
import net.minecraft.client.option.GameSettings;
76
import net.minecraft.client.option.KeyBinding;
@@ -24,7 +23,6 @@ public class GameSettingsMixin implements FreecamOptions {
2423
return freecamBind;
2524
}
2625

27-
2826
@Override
2927
public @NotNull OptionBoolean getFreecam() {
3028
return freecam;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package me.apollointhehouse.mixin;
2+
3+
import net.minecraft.core.player.gamemode.Gamemode;
4+
import org.spongepowered.asm.mixin.Mixin;
5+
import org.spongepowered.asm.mixin.gen.Accessor;
6+
7+
@Mixin(value = Gamemode.class, remap = false)
8+
public interface GamemodeAccessor {
9+
@Accessor("canInteract")
10+
void setCanInteract(boolean canInteract);
11+
}

src/main/java/me/apollointhehouse/mixin/ScreenMainMenuMixin.java

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,25 @@
11
package me.apollointhehouse
22

3-
import me.apollointhehouse.options.FreecamOptions
4-
import me.apollointhehouse.raywire.Raywire
5-
import me.apollointhehouse.raywire.api.EventHandler
6-
import me.apollointhehouse.raywire.api.event.core.network.PacketEvent
7-
import net.fabricmc.api.ModInitializer
8-
import net.minecraft.client.Minecraft
9-
import net.minecraft.client.gui.options.components.BooleanOptionComponent
10-
import net.minecraft.client.gui.options.data.OptionsPages
11-
import net.minecraft.core.net.packet.PacketMovePlayer
12-
import net.minecraft.core.player.gamemode.Gamemode
13-
import net.minecraft.core.util.phys.Vec3
14-
import org.slf4j.Logger
3+
import me.apollointhehouse.net.client.ClientLogic
4+
import me.apollointhehouse.net.server.ServerLogic
5+
import me.apollointhehouse.raywire.Raywire.registry
156
import org.slf4j.LoggerFactory
16-
import turniplabs.halplibe.util.ClientStartEntrypoint
17-
18-
object Freecam : ModInitializer, ClientStartEntrypoint {
19-
const val MOD_ID: String = "freecam"
20-
@JvmField val LOGGER: Logger = LoggerFactory.getLogger(MOD_ID)
21-
22-
private val options by lazy { Minecraft.getMinecraft().gameSettings as FreecamOptions }
23-
private var toggled = false
24-
private var oldPos = Vec3.getPermanentVec3(0.0,0.0,0.0)
25-
private var oldGamemode = Gamemode.spectator
26-
27-
override fun onInitialize() {
28-
LOGGER.info("Freecam initialized.")
29-
30-
Raywire.registry.subscribe(this)
31-
}
32-
33-
override fun beforeClientStart() {
34-
}
35-
36-
override fun afterClientStart() {
37-
options.freecam.addCallback { option ->
38-
val mc = Minecraft.getMinecraft()
39-
val player = mc.thePlayer
40-
41-
if (!option.value) {
42-
player.gamemode = oldGamemode
43-
player.moveTo(oldPos.x,oldPos.y,oldPos.z, player.xRot, player.yRot)
44-
45-
return@addCallback
46-
}
47-
48-
oldGamemode = player.gamemode
49-
oldPos = Vec3.getPermanentVec3(player.x, player.bb.minY, player.z)
50-
mc.thePlayer.gamemode = Gamemode.spectator
7+
import turniplabs.halplibe.helper.EnvironmentHelper
8+
import turniplabs.halplibe.util.GameStartEntrypoint
9+
10+
object Freecam : GameStartEntrypoint {
11+
const val MOD_ID = "freecam"
12+
private val logger = LoggerFactory.getLogger(MOD_ID)
13+
14+
override fun afterGameStart() {
15+
if (EnvironmentHelper.isServerEnvironment()) {
16+
logger.info("Freecam server started.")
17+
registry.subscribe(ServerLogic())
18+
} else {
19+
logger.info("Freecam client started.")
20+
registry.subscribe(ClientLogic())
5121
}
52-
53-
OptionsPages.GENERAL.withComponent(BooleanOptionComponent(options.freecam))
5422
}
5523

56-
57-
@EventHandler
58-
fun onSendPacket(event: PacketEvent.Send) {
59-
if (event.packet !is PacketMovePlayer) return
60-
if (!toggled) return
61-
62-
event.cancel()
63-
}
24+
override fun beforeGameStart() {}
6425
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@file:OptIn(ExperimentalStdlibApi::class)
2+
package me.apollointhehouse.modules
3+
4+
import me.apollointhehouse.mixin.GamemodeAccessor
5+
import me.apollointhehouse.options.FreecamOptions
6+
import me.apollointhehouse.raywire.api.EventHandler
7+
import me.apollointhehouse.raywire.api.event.core.network.PacketEvent
8+
import net.minecraft.client.gui.options.components.BooleanOptionComponent
9+
import net.minecraft.client.gui.options.data.OptionsPages
10+
import net.minecraft.core.net.packet.PacketMovePlayer
11+
import net.minecraft.core.util.phys.Vec3
12+
import org.slf4j.LoggerFactory
13+
14+
object FreecamMod : Module() {
15+
private var oldPos = Vec3.getPermanentVec3(0.0,0.0,0.0)
16+
17+
init {
18+
val options = mc.gameSettings as FreecamOptions
19+
20+
options.freecam.addCallback { option ->
21+
if (!option.value) {
22+
disable()
23+
return@addCallback
24+
}
25+
enable()
26+
}
27+
28+
OptionsPages.GENERAL.withComponent(BooleanOptionComponent(options.freecam))
29+
}
30+
31+
override fun onEnable() {
32+
oldPos = Vec3.getPermanentVec3(player.x, player.bb.minY, player.z)
33+
player.noPhysics = true
34+
(player.gamemode as GamemodeAccessor).setCanInteract(false)
35+
}
36+
37+
override fun onDisable() {
38+
player.moveTo(oldPos.x,oldPos.y,oldPos.z, 0f, 0f)
39+
40+
player.noPhysics = false
41+
(player.gamemode as GamemodeAccessor).setCanInteract(true)
42+
}
43+
44+
@EventHandler
45+
fun onSendPacket(event: PacketEvent.Send) {
46+
if (event.packet is PacketMovePlayer) event.cancel()
47+
}
48+
49+
private val logger = LoggerFactory.getLogger(FreecamMod::class.java)
50+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.apollointhehouse.modules
2+
3+
import me.apollointhehouse.raywire.Raywire.registry
4+
import net.minecraft.client.Minecraft
5+
import net.minecraft.client.entity.player.PlayerLocal
6+
7+
abstract class Module {
8+
var enabled = false
9+
private set
10+
11+
protected val mc: Minecraft = Minecraft.getMinecraft()
12+
protected val player: PlayerLocal get() = mc.thePlayer
13+
14+
open fun onEnable() {}
15+
open fun onDisable() {}
16+
17+
fun disable() {
18+
if (!enabled) return
19+
20+
enabled = false
21+
registry.unsubscribe(this)
22+
onDisable()
23+
}
24+
25+
fun enable() {
26+
if (enabled) return
27+
28+
enabled = true
29+
onEnable()
30+
registry.subscribe(this)
31+
}
32+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package me.apollointhehouse.net.client
2+
3+
import me.apollointhehouse.modules.FreecamMod
4+
import me.apollointhehouse.raywire.api.EventHandler
5+
import me.apollointhehouse.raywire.api.event.core.network.PacketEvent
6+
import net.minecraft.client.Minecraft
7+
import net.minecraft.core.net.packet.PacketAESSendKey
8+
import net.minecraft.core.net.packet.PacketCustomPayload
9+
import org.slf4j.LoggerFactory
10+
11+
class ClientLogic {
12+
@EventHandler
13+
fun onLogin(event: PacketEvent.Receive) {
14+
if (event.packet !is PacketAESSendKey) return
15+
FreecamMod.disable()
16+
17+
val mc = Minecraft.getMinecraft()
18+
19+
logger.info("Sending Freecam Request to server...")
20+
mc.sendQueue.addToSendQueue(PacketCustomPayload("Freecam", byteArrayOf(0x00)))
21+
}
22+
23+
@OptIn(ExperimentalStdlibApi::class)
24+
@EventHandler
25+
fun onCustomPayload(event: PacketEvent.Receive) {
26+
val packet = event.packet as? PacketCustomPayload ?: return
27+
28+
if (packet.channel != "Freecam") return
29+
if (packet.data.isEmpty()) return
30+
31+
when (val data = packet.data.first()) {
32+
0x01.toByte() -> {
33+
logger.info("Freecam Supported!")
34+
FreecamMod
35+
}
36+
else -> {
37+
logger.info("Unknown Freecam data received: ${data.toHexString()}")
38+
}
39+
}
40+
}
41+
42+
companion object {
43+
private val logger = LoggerFactory.getLogger(ClientLogic::class.java)
44+
}
45+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package me.apollointhehouse.net.server
2+
3+
import me.apollointhehouse.raywire.api.EventHandler
4+
import me.apollointhehouse.raywire.api.event.core.network.PacketEvent
5+
import net.minecraft.core.net.packet.PacketCustomPayload
6+
import net.minecraft.server.MinecraftServer
7+
import org.slf4j.LoggerFactory
8+
9+
class ServerLogic {
10+
@OptIn(ExperimentalStdlibApi::class)
11+
@EventHandler
12+
fun onCustomPayload(event: PacketEvent.Receive) {
13+
val packet = event.packet as? PacketCustomPayload ?: return
14+
15+
if (packet.channel != "Freecam") return
16+
if (packet.data.isEmpty()) return
17+
18+
when (val data = packet.data.first()) {
19+
0x00.toByte() -> {
20+
logger.info("Handling Freecam Request!")
21+
MinecraftServer.getInstance().playerList.sendPacketToAllPlayers(
22+
PacketCustomPayload(
23+
"Freecam",
24+
byteArrayOf(0x01)
25+
)
26+
)
27+
}
28+
else -> {
29+
logger.info("Unknown Freecam data received: ${data.toHexString()}")
30+
}
31+
}
32+
}
33+
34+
companion object {
35+
private val logger = LoggerFactory.getLogger(ServerLogic::class.java)
36+
}
37+
}

0 commit comments

Comments
 (0)