From 789e8834e3bf556a3f75b328459fade0ea7a362a Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 14 Dec 2022 16:52:37 +0100 Subject: [PATCH] forbid server to update local skin layers --- .../profile/profiles/connection/skin/SkinC.kt | 46 +++++++++---------- .../entities/entities/player/PlayerEntity.kt | 21 ++++----- .../player/local/LocalPlayerEntity.kt | 5 ++ .../world/overlay/overlays/arm/ArmOverlay.kt | 1 + .../play/settings/ClientSettingsManager.kt | 31 +++++-------- 5 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/connection/skin/SkinC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/connection/skin/SkinC.kt index 31b5c32e6..c01f0681d 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/connection/skin/SkinC.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/connection/skin/SkinC.kt @@ -14,6 +14,8 @@ package de.bixilon.minosoft.config.profile.profiles.connection.skin import com.fasterxml.jackson.annotation.JsonIgnore +import de.bixilon.kutil.observer.DataObserver.Companion.observe +import de.bixilon.kutil.observer.set.SetObserver.Companion.observedSet import de.bixilon.minosoft.config.profile.delegate.primitive.BooleanDelegate import de.bixilon.minosoft.config.profile.profiles.connection.ConnectionProfile import de.bixilon.minosoft.data.entities.entities.player.SkinParts @@ -62,30 +64,24 @@ class SkinC(profile: ConnectionProfile) { var hat by BooleanDelegate(profile, true) - @get:JsonIgnore val skinParts: Array - get() { - val parts: MutableSet = mutableSetOf() - if (cape) { - parts += SkinParts.CAPE - } - if (jacket) { - parts += SkinParts.JACKET - } - if (leftSleeve) { - parts += SkinParts.LEFT_SLEEVE - } - if (rightSleeve) { - parts += SkinParts.RIGHT_SLEEVE - } - if (leftPants) { - parts += SkinParts.LEFT_PANTS - } - if (rightPants) { - parts += SkinParts.RIGHT_PANTS - } - if (hat) { - parts += SkinParts.HAT - } - return parts.toTypedArray() + @get:JsonIgnore val parts: MutableSet by observedSet(mutableSetOf()) + + private fun updateParts(part: SkinParts, add: Boolean) { + if (add) { + parts += part + } else { + parts -= part } + } + + + init { + this::cape.observe(this, true) { updateParts(SkinParts.CAPE, it) } + this::jacket.observe(this, true) { updateParts(SkinParts.JACKET, it) } + this::leftSleeve.observe(this, true) { updateParts(SkinParts.LEFT_SLEEVE, it) } + this::rightSleeve.observe(this, true) { updateParts(SkinParts.RIGHT_SLEEVE, it) } + this::leftPants.observe(this, true) { updateParts(SkinParts.LEFT_PANTS, it) } + this::rightPants.observe(this, true) { updateParts(SkinParts.RIGHT_PANTS, it) } + this::hat.observe(this, true) { updateParts(SkinParts.HAT, it) } + } } diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/PlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/PlayerEntity.kt index 34095476c..f63f01082 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/PlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/PlayerEntity.kt @@ -82,22 +82,19 @@ abstract class PlayerEntity( val skinParts: MutableSet by observedSet(mutableSetOf()) - init { - data.observe(SKIN_PARTS_DATA) { raw: Any? -> - if (raw == null) { - skinParts.clear() - return@observe - } - val flags = raw.toInt() - for (part in SkinParts.VALUES) { - if (!flags.isBitMask(part.bitmask)) { - skinParts -= part - } - skinParts += part + protected open fun updateSkinParts(flags: Int) { + for (part in SkinParts.VALUES) { + if (!flags.isBitMask(part.bitmask)) { + skinParts -= part } + skinParts += part } } + init { + data.observe(SKIN_PARTS_DATA) { raw: Any? -> updateSkinParts(raw?.toInt() ?: 0) } + } + @get:SynchronizedEntityData open val mainArm: Arms get() = if (data.get(MAIN_ARM_DATA, 0x00.toByte()).toInt() == 0x01) Arms.RIGHT else Arms.LEFT diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt index 84e337f44..7b41cbc97 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/player/local/LocalPlayerEntity.kt @@ -30,6 +30,7 @@ import de.bixilon.kutil.collections.map.bi.SynchronizedBiMap import de.bixilon.kutil.math.interpolation.DoubleInterpolation.interpolateLinear import de.bixilon.kutil.observer.DataObserver.Companion.observe import de.bixilon.kutil.observer.DataObserver.Companion.observed +import de.bixilon.kutil.observer.set.SetObserver.Companion.observeSet import de.bixilon.kutil.primitive.BooleanUtil.decide import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.minosoft.data.Axes @@ -105,6 +106,7 @@ class LocalPlayerEntity( equipment.remove(EquipmentSlots.MAIN_HAND) equipment[EquipmentSlots.MAIN_HAND] = inventory.getHotbarSlot(it) ?: return@observe } + connection.profiles.connection.skin::parts.observeSet(this, true) { skinParts += it.adds; skinParts -= it.removes } } var openedContainer: Container? = null @@ -593,6 +595,9 @@ class LocalPlayerEntity( override val pushableByFluids: Boolean get() = !baseAbilities.isFlying + + override fun updateSkinParts(flags: Int) = Unit + override fun tick() { if (connection.world[positionInfo.blockPosition.chunkPosition] == null) { // chunk not loaded, so we don't tick? diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt index 9586715d4..e032744d5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt @@ -56,6 +56,7 @@ class ArmOverlay(private val renderWindow: RenderWindow) : Overlay { private fun poll() { val model = renderWindow.connection.player.model.nullCast() val skin = model?.skin + // TODO: check skin parts if (this.model == model && this.skin == skin) { return } diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/settings/ClientSettingsManager.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/settings/ClientSettingsManager.kt index 6c9a0ce2f..87a3593f2 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/settings/ClientSettingsManager.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/settings/ClientSettingsManager.kt @@ -44,15 +44,6 @@ class ClientSettingsManager( profile::mainArm.observe(this) { sendClientSettings() } profile::playerListing.observe(this) { sendClientSettings() } - val skin = profile.skin - skin::cape.observe(this) { sendClientSettings() } - skin::jacket.observe(this) { sendClientSettings() } - skin::leftSleeve.observe(this) { sendClientSettings() } - skin::rightSleeve.observe(this) { sendClientSettings() } - skin::leftPants.observe(this) { sendClientSettings() } - skin::rightPants.observe(this) { sendClientSettings() } - skin::hat.observe(this) { sendClientSettings() } - profile::language.observe(this) { sendLanguage() } connection.profiles.eros.general::language.observe(this) { sendLanguage() } } @@ -72,15 +63,17 @@ class ClientSettingsManager( if (connection.network.state != ProtocolStates.PLAY) { return } - connection.sendPacket(SettingsC2SP( - locale = language, - chatColors = connection.profiles.gui.chat.chatColors, - viewDistance = connection.profiles.block.viewDistance, - chatMode = connection.profiles.gui.chat.chatMode, - skinParts = profile.skin.skinParts, - mainArm = profile.mainArm, - disableTextFiltering = !connection.profiles.gui.chat.textFiltering, - allowListing = profile.playerListing, - )) + connection.sendPacket( + SettingsC2SP( + locale = language, + chatColors = connection.profiles.gui.chat.chatColors, + viewDistance = connection.profiles.block.viewDistance, + chatMode = connection.profiles.gui.chat.chatMode, + skinParts = profile.skin.parts.toTypedArray(), + mainArm = profile.mainArm, + disableTextFiltering = !connection.profiles.gui.chat.textFiltering, + allowListing = profile.playerListing, + ) + ) } }