Skip to content

Commit dfe288c

Browse files
committed
fix: skull property setting
1 parent afcfbec commit dfe288c

File tree

1 file changed

+52
-40
lines changed

1 file changed

+52
-40
lines changed

src/main/kotlin/util/mc/SkullItemData.kt

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
package moe.nea.firmament.util.mc
44

5+
import com.google.common.collect.Multimap
6+
import com.google.common.collect.Multimaps
57
import com.mojang.authlib.GameProfile
68
import com.mojang.authlib.minecraft.MinecraftProfileTexture
79
import com.mojang.authlib.properties.Property
10+
import com.mojang.authlib.properties.PropertyMap
811
import java.time.Instant
912
import java.util.UUID
1013
import kotlinx.serialization.Serializable
@@ -21,66 +24,75 @@ import moe.nea.firmament.util.json.InstantAsLongSerializer
2124

2225
@Serializable
2326
data class MinecraftProfileTextureKt(
24-
val url: String,
25-
val metadata: Map<String, String> = mapOf(),
27+
val url: String,
28+
val metadata: Map<String, String> = mapOf(),
2629
)
2730

2831
@Serializable
2932
data class MinecraftTexturesPayloadKt(
30-
val textures: Map<MinecraftProfileTexture.Type, MinecraftProfileTextureKt> = mapOf(),
31-
val profileId: UUID? = null,
32-
val profileName: String? = null,
33-
val isPublic: Boolean = true,
34-
val timestamp: Instant = Instant.now(),
33+
val textures: Map<MinecraftProfileTexture.Type, MinecraftProfileTextureKt> = mapOf(),
34+
val profileId: UUID? = null,
35+
val profileName: String? = null,
36+
val isPublic: Boolean = true,
37+
val timestamp: Instant = Instant.now(),
3538
)
3639

37-
fun GameProfile.setTextures(textures: MinecraftTexturesPayloadKt) {
38-
val json = Firmament.json.encodeToString(textures)
39-
val encoded = java.util.Base64.getEncoder().encodeToString(json.encodeToByteArray())
40-
properties.put(propertyTextures, Property(propertyTextures, encoded))
40+
fun createSkullTextures(textures: MinecraftTexturesPayloadKt): PropertyMap {
41+
val json = Firmament.json.encodeToString(textures)
42+
val encoded = java.util.Base64.getEncoder().encodeToString(json.encodeToByteArray())
43+
return PropertyMap(
44+
Multimaps.forMap(mapOf(propertyTextures to Property(propertyTextures, encoded)))
45+
)
4146
}
4247

4348
private val propertyTextures = "textures"
4449

4550
fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) {
46-
assert(this.item == Items.PLAYER_HEAD)
47-
val gameProfile = GameProfile(uuid, "LameGuy123")
48-
gameProfile.properties.put(propertyTextures, Property(propertyTextures, encodedData.padToValidBase64()))
49-
this.set(DataComponents.PROFILE, ResolvableProfile.createResolved(gameProfile))
51+
assert(this.item == Items.PLAYER_HEAD)
52+
val gameProfile = GameProfile(
53+
uuid, "LameGuy123",
54+
PropertyMap(
55+
Multimaps.forMap(
56+
mapOf(propertyTextures to Property(propertyTextures, encodedData.padToValidBase64()))
57+
)
58+
)
59+
)
60+
this.set(DataComponents.PROFILE, ResolvableProfile.createResolved(gameProfile))
5061
}
5162

5263
val arbitraryUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
5364
fun createSkullItem(uuid: UUID, url: String) = ItemStack(Items.PLAYER_HEAD)
54-
.also { it.setSkullOwner(uuid, url) }
65+
.also { it.setSkullOwner(uuid, url) }
5566

5667
fun ItemStack.setSkullOwner(uuid: UUID, url: String) {
57-
assert(this.item == Items.PLAYER_HEAD)
58-
val gameProfile = GameProfile(uuid, "nea89")
59-
gameProfile.setTextures(
60-
MinecraftTexturesPayloadKt(
61-
textures = mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)),
62-
profileId = uuid,
63-
profileName = "nea89",
64-
)
65-
)
66-
this.set(DataComponents.PROFILE, ResolvableProfile.createResolved(gameProfile))
68+
assert(this.item == Items.PLAYER_HEAD)
69+
val gameProfile = GameProfile(
70+
uuid, "nea89", createSkullTextures(
71+
MinecraftTexturesPayloadKt(
72+
textures = mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)),
73+
profileId = uuid,
74+
profileName = "nea89",
75+
)
76+
)
77+
)
78+
this.set(DataComponents.PROFILE, ResolvableProfile.createResolved(gameProfile))
6779
}
6880

6981

7082
fun decodeProfileTextureProperty(property: Property): MinecraftTexturesPayloadKt? {
71-
assertTrueOr(property.name == propertyTextures) { return null }
72-
return try {
73-
var encodedF: String = property.value
74-
while (encodedF.length % 4 != 0 && encodedF.last() == '=') {
75-
encodedF = encodedF.substring(0, encodedF.length - 1)
76-
}
77-
val json = java.util.Base64.getDecoder().decode(encodedF).decodeToString()
78-
Firmament.json.decodeFromString<MinecraftTexturesPayloadKt>(json)
79-
} catch (e: Exception) {
80-
// Malformed profile data
81-
if (Firmament.DEBUG)
82-
e.printStackTrace()
83-
null
84-
}
83+
assertTrueOr(property.name == propertyTextures) { return null }
84+
return try {
85+
var encodedF: String = property.value
86+
while (encodedF.length % 4 != 0 && encodedF.last() == '=') {
87+
encodedF = encodedF.substring(0, encodedF.length - 1)
88+
}
89+
val json = java.util.Base64.getDecoder().decode(encodedF).decodeToString()
90+
Firmament.json.decodeFromString<MinecraftTexturesPayloadKt>(json)
91+
} catch (e: Exception) {
92+
// Malformed profile data
93+
if (Firmament.DEBUG)
94+
e.printStackTrace()
95+
null
96+
}
8597
}
8698

0 commit comments

Comments
 (0)