Skip to content

Commit

Permalink
fix: tag-packets being incomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
Boy0000 committed Jul 29, 2024
1 parent a89af89 commit dff3c88
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 83 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
group=com.mineinabyss
version=0.22
idofrontVersion=0.24.0-dev.8
version=0.23
idofrontVersion=0.24.15
4 changes: 1 addition & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[versions]
geary = "0.30.1-dev.10"
bonehurtingjuice = "1.10.1"
geary = "0.30.10-dev.1"

[libraries]
geary-papermc = { module = "com.mineinabyss:geary-papermc", version.ref = "geary" }
bonehurtingjuice = { module = "com.mineinabyss:bonehurtingjuice", version.ref = "bonehurtingjuice" }
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,34 @@ package com.mineinabyss.staminaclimb
import com.mineinabyss.geary.autoscan.autoscan
import com.mineinabyss.geary.modules.geary
import com.mineinabyss.idofront.di.DI
import com.mineinabyss.idofront.nms.interceptClientbound
import com.mineinabyss.idofront.plugin.listeners
import com.mineinabyss.staminaclimb.climbing.ClimbBehaviour
import com.mineinabyss.staminaclimb.climbing.ClimbBehaviour.stopClimbing
import com.mineinabyss.staminaclimb.modules.StaminaClimbModule
import com.mineinabyss.staminaclimb.modules.StaminaPaperModule
import com.mineinabyss.staminaclimb.modules.stamina
import com.mineinabyss.staminaclimb.nms.Tags
import com.mineinabyss.staminaclimb.nms.Tags.networkPayload
import com.mineinabyss.staminaclimb.nms.Tags.tags
import com.mineinabyss.staminaclimb.stamina.StaminaBar
import com.mineinabyss.staminaclimb.stamina.StaminaBar.registerBar
import com.mineinabyss.staminaclimb.stamina.StaminaTask
import it.unimi.dsi.fastutil.ints.IntList
import net.minecraft.core.registries.Registries
import net.minecraft.network.protocol.Packet
import net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.BlockTags
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin

/** A reference to the StaminaClimb plugin */

class StaminaClimbPlugin : JavaPlugin() {
override fun onLoad() {
DI.add<StaminaClimbModule>(StaminaPaperModule(this))
createClimbContext()
geary {
autoscan(classLoader, "com.mineinabyss.staminaclimb") {
all()
Expand All @@ -34,6 +46,13 @@ class StaminaClimbPlugin : JavaPlugin() {

listeners(ClimbBehaviour, StaminaBar)
StaminaCommands()

Tags.interceptConfigPhaseTagPacket()
}

fun createClimbContext() {
DI.remove<StaminaClimbModule>()
DI.add<StaminaClimbModule>(StaminaPaperModule(this))
}

override fun onDisable() {
Expand Down
17 changes: 10 additions & 7 deletions src/main/kotlin/com/mineinabyss/staminaclimb/StaminaCommands.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import com.mineinabyss.idofront.messaging.info
import com.mineinabyss.idofront.messaging.success
import com.mineinabyss.staminaclimb.modules.stamina
import com.mineinabyss.staminaclimb.nms.Tags
import net.minecraft.core.Registry
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.tags.BlockTags
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter
import kotlin.jvm.optionals.getOrNull

class StaminaCommands : IdofrontCommandExecutor(), TabCompleter {
override val commands = commands(stamina.plugin) {
Expand All @@ -25,18 +28,18 @@ class StaminaCommands : IdofrontCommandExecutor(), TabCompleter {
"staminaclimb" {
"reload" {
action {
stamina.configHolder.reload()
stamina.plugin.createClimbContext()
sender.success("Config has been reloaded!")
}
}
"tags" {
action {
stamina.emptyClimbableMap.entries.find { it.key == BlockTags.FALL_DAMAGE_RESETTING.location }?.let {
sender.info("Fall damage resetting tag: ${it.value}")
}
stamina.normalClimbableMap.entries.find { it.key == BlockTags.CLIMBABLE.location }?.let {
sender.info("Climbable tag: ${it.value}")
}
// stamina.emptyClimbableMap.entries.find { it.key == BlockTags.CLIMBABLE.location }?.let {
// sender.info("Empty climbable tag: ${it.value.joinToString { BuiltInRegistries.BLOCK.getHolder(it).getOrNull()?.registeredName.toString() }}")
// }
// stamina.normalClimbableMap.entries.find { it.key == BlockTags.CLIMBABLE.location }?.let {
// sender.info("Normal Climbable Tag: ${it.value.joinToString { BuiltInRegistries.BLOCK.getHolder(it).getOrNull()?.registeredName.toString() }}")
// }
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.mineinabyss.staminaclimb.modules

import com.mineinabyss.idofront.config.IdofrontConfig
import com.mineinabyss.idofront.di.DI
import com.mineinabyss.staminaclimb.StaminaClimbPlugin
import com.mineinabyss.staminaclimb.config.StaminaConfig
import it.unimi.dsi.fastutil.ints.IntArrayList
import net.minecraft.resources.ResourceLocation
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.tags.TagNetworkSerialization.NetworkPayload

val stamina: StaminaClimbModule by DI.observe()

interface StaminaClimbModule {
val plugin: StaminaClimbPlugin
val configHolder: IdofrontConfig<StaminaConfig>
val config: StaminaConfig
val emptyClimbableMap: Map<ResourceLocation, IntArrayList>
val normalClimbableMap: Map<ResourceLocation, IntArrayList>
val disabledClimbingTags: MutableMap<ResourceKey<out Registry<*>?>, NetworkPayload>
val initialTags: MutableMap<ResourceKey<out Registry<*>?>, NetworkPayload>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import com.mineinabyss.idofront.config.config
import com.mineinabyss.staminaclimb.StaminaClimbPlugin
import com.mineinabyss.staminaclimb.config.StaminaConfig
import com.mineinabyss.staminaclimb.nms.Tags
import it.unimi.dsi.fastutil.ints.IntArrayList
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagNetworkSerialization.NetworkPayload

class StaminaPaperModule(
override val plugin: StaminaClimbPlugin
) : StaminaClimbModule {
override val configHolder: IdofrontConfig<StaminaConfig> =
config("config", plugin.dataFolder.toPath(), StaminaConfig())
override val config: StaminaConfig by configHolder
override val emptyClimbableMap = Tags.createEmptyClimbableMap()
override val normalClimbableMap = Tags.createNormalClimbableMap()
override val config by config("config", plugin.dataPath, StaminaConfig())
override val disabledClimbingTags: MutableMap<ResourceKey<out Registry<*>?>, NetworkPayload> = mutableMapOf()
override val initialTags: MutableMap<ResourceKey<out Registry<*>?>, NetworkPayload> = mutableMapOf()
}
88 changes: 38 additions & 50 deletions src/main/kotlin/com/mineinabyss/staminaclimb/nms/Tags.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.mineinabyss.staminaclimb.nms

import com.mineinabyss.idofront.nms.interceptClientbound
import com.mineinabyss.staminaclimb.modules.stamina
import it.unimi.dsi.fastutil.ints.IntArrayList
import it.unimi.dsi.fastutil.ints.IntList
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.core.registries.Registries
import net.minecraft.network.protocol.Packet
import net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.BlockTags
Expand All @@ -13,67 +13,55 @@ import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player

object Tags {
fun createPayload(map: Map<ResourceLocation, IntList>): NetworkPayload =
NetworkPayload::class.java.declaredConstructors.first()
.also { it.isAccessible = true }
.newInstance(map) as NetworkPayload

val disabledPlayers = mutableSetOf<Player>()

/**
* Intercepts ClientboundUpdateTagsPacket sent to players during Configuration Phase & caches it.
*
* It then caches the initial tag-set and generates a copy without climbable & fall_damage_resetting entries
*/
fun interceptConfigPhaseTagPacket() {
stamina.plugin.interceptClientbound { packet: Packet<*>, player: Player? ->
if (packet !is ClientboundUpdateTagsPacket || player?.isOnline == true) return@interceptClientbound packet
if (stamina.initialTags.isNotEmpty()) return@interceptClientbound packet

stamina.initialTags.putAll(packet.tags)
packet.tags.entries.map { registryEntry ->
if (registryEntry.key == Registries.BLOCK) {
val tags = registryEntry.value.tags().map { tag ->
tag.key to when (tag.key) {
BlockTags.CLIMBABLE.location, BlockTags.FALL_DAMAGE_RESETTING.location -> IntList.of()
else -> tag.value
}
}.toMap()
registryEntry.setValue(tags.networkPayload())
}
registryEntry
}.forEach {
stamina.disabledClimbingTags[it.key] = it.value
}

return@interceptClientbound packet
}
}

fun enableClimb(player: Player) {
if (player !in disabledPlayers) return
disabledPlayers.remove(player)
(player as CraftPlayer).handle.connection.send(updateTagPacket(true))
(player as CraftPlayer).handle.connection.send(ClientboundUpdateTagsPacket(stamina.initialTags))
}

fun disableClimb(player: Player) {
if (player in disabledPlayers) return
disabledPlayers.add(player)

(player as CraftPlayer).handle.connection.send(updateTagPacket(false))
}

private fun updateTagPacket(enable: Boolean): ClientboundUpdateTagsPacket {
return ClientboundUpdateTagsPacket(
mapOf(
Registries.BLOCK to createPayload(
when (enable) {
true -> stamina.normalClimbableMap
false -> stamina.emptyClimbableMap
}
)
)
)
(player as CraftPlayer).handle.connection.send(ClientboundUpdateTagsPacket(stamina.disabledClimbingTags))
}

fun emptyFallDamageResetTag(player: Player): Map<ResourceLocation, IntArrayList> {
return BuiltInRegistries.BLOCK.tags.map { pair ->
pair.first.location to IntArrayList(pair.second.size()).apply {
if (pair.first.location == BlockTags.FALL_DAMAGE_RESETTING.location) return@apply
if (player in disabledPlayers && pair.first.location == BlockTags.CLIMBABLE.location) return@apply
pair.second.forEach { add(BuiltInRegistries.BLOCK.getId(it.value())) }
}
}.toList().toMap()
}

fun createNormalClimbableMap(): Map<ResourceLocation, IntArrayList> {
return BuiltInRegistries.BLOCK.tags.map { pair ->
pair.first.location to IntArrayList(pair.second.size()).apply {
if (pair.first.location == BlockTags.FALL_DAMAGE_RESETTING.location) return@apply
pair.second.forEach { add(BuiltInRegistries.BLOCK.getId(it.value())) }
}
}.toList().toMap()
}
private val tagsField = NetworkPayload::class.java.getDeclaredField("tags").also { it.isAccessible = true }
private val payloadConstructor = NetworkPayload::class.java.declaredConstructors.first().also { it.isAccessible = true }
fun NetworkPayload.tags() = (tagsField.get(this) as Map<ResourceLocation, IntList>).toMutableMap()
fun Map<ResourceLocation, IntList>.networkPayload() = payloadConstructor.newInstance(this) as NetworkPayload

fun createEmptyClimbableMap(): Map<ResourceLocation, IntArrayList> {
return BuiltInRegistries.BLOCK.tags.map { pair ->
pair.first.location to IntArrayList(pair.second.size()).apply {
// If the tag is CLIMBABLE, don't add any blocks to the list
when (pair.first.location) {
BlockTags.CLIMBABLE.location, BlockTags.FALL_DAMAGE_RESETTING.location -> return@apply
else -> pair.second.forEach { add(BuiltInRegistries.BLOCK.getId(it.value())) }
}
}
}.toList().toMap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.mineinabyss.staminaclimb.*
import com.mineinabyss.staminaclimb.climbing.ClimbBehaviour
import com.mineinabyss.staminaclimb.modules.stamina
import com.mineinabyss.staminaclimb.nms.Tags
import com.mineinabyss.staminaclimb.nms.Tags.createPayload
import kotlinx.coroutines.delay
import net.kyori.adventure.bossbar.BossBar
import net.minecraft.core.registries.Registries
Expand Down Expand Up @@ -81,9 +80,6 @@ object StaminaBar : Listener {

@EventHandler
fun PlayerJoinEvent.onPlayerJoin() {
val map = Tags.emptyFallDamageResetTag(player)
val packet = ClientboundUpdateTagsPacket(mapOf(Registries.BLOCK to createPayload(map)))
(player as CraftPlayer).handle.connection.send(packet)
registerBar(player)
if (player.isClimbing && player.uniqueId in barProgressTracker) {
player.setStamina(barProgressTracker[player.uniqueId]!!)
Expand Down
6 changes: 1 addition & 5 deletions src/main/resources/paper-plugin.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: StaminaClimb
version: '${plugin_version}'
author: Offz
api-version: '1.20'
api-version: '1.21'
main: com.mineinabyss.staminaclimb.StaminaClimbPlugin
prefix: SnC
description: A mod that lets you climb and get exhausted
Expand All @@ -12,7 +12,3 @@ dependencies:
required: true
load: BEFORE
join-classpath: true
BoneHurtingJuice:
required: false
load: BEFORE
join-classpath: true

0 comments on commit dff3c88

Please sign in to comment.