Add basic sack util

[no changelog]
This commit is contained in:
Linnea Gräf
2024-10-01 18:00:43 +02:00
parent beb14d73bd
commit a4eac70118
22 changed files with 350 additions and 177 deletions

View File

@@ -0,0 +1,28 @@
package moe.nea.firmament.util.mc
import java.util.Spliterator
import java.util.Spliterators
import net.minecraft.inventory.Inventory
import net.minecraft.item.ItemStack
val Inventory.indices get() = 0 until size()
val Inventory.iterableView
get() = object : Iterable<ItemStack> {
override fun spliterator(): Spliterator<ItemStack> {
return Spliterators.spliterator(iterator(), size().toLong(), 0)
}
override fun iterator(): Iterator<ItemStack> {
return object : Iterator<ItemStack> {
var i = 0
override fun hasNext(): Boolean {
return i < size()
}
override fun next(): ItemStack {
if (!hasNext()) throw NoSuchElementException()
return getStack(i++)
}
}
}
}

View File

@@ -0,0 +1,20 @@
package moe.nea.firmament.util.mc
import net.minecraft.item.ItemStack
import net.minecraft.text.Text
fun ItemStack.appendLore(args: List<Text>) {
if (args.isEmpty()) return
modifyLore {
val loreList = loreAccordingToNbt.toMutableList()
for (arg in args) {
loreList.add(arg)
}
loreList
}
}
fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) {
val loreList = loreAccordingToNbt
loreAccordingToNbt = update(loreList)
}

View File

@@ -0,0 +1,22 @@
package moe.nea.firmament.util.mc
import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.LoreComponent
import net.minecraft.item.ItemStack
import net.minecraft.text.Text
var ItemStack.loreAccordingToNbt
get() = get(DataComponentTypes.LORE)?.lines ?: listOf()
set(value) {
set(DataComponentTypes.LORE, LoreComponent(value))
}
var ItemStack.displayNameAccordingToNbt: Text
get() = get(DataComponentTypes.CUSTOM_NAME) ?: get(DataComponentTypes.ITEM_NAME) ?: item.name
set(value) {
set(DataComponentTypes.CUSTOM_NAME, value)
}
fun ItemStack.setCustomName(text: Text) {
set(DataComponentTypes.CUSTOM_NAME, text)
}

View File

@@ -0,0 +1,88 @@
@file:UseSerializers(DashlessUUIDSerializer::class, InstantAsLongSerializer::class)
package moe.nea.firmament.util.mc
import com.mojang.authlib.GameProfile
import com.mojang.authlib.minecraft.MinecraftProfileTexture
import com.mojang.authlib.properties.Property
import java.util.UUID
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlinx.serialization.encodeToString
import net.minecraft.component.DataComponentTypes
import net.minecraft.component.type.ProfileComponent
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
import moe.nea.firmament.Firmament
import moe.nea.firmament.util.Base64Util.padToValidBase64
import moe.nea.firmament.util.assertTrueOr
import moe.nea.firmament.util.json.DashlessUUIDSerializer
import moe.nea.firmament.util.json.InstantAsLongSerializer
@Serializable
data class MinecraftProfileTextureKt(
val url: String,
val metadata: Map<String, String> = mapOf(),
)
@Serializable
data class MinecraftTexturesPayloadKt(
val textures: Map<MinecraftProfileTexture.Type, MinecraftProfileTextureKt> = mapOf(),
val profileId: UUID? = null,
val profileName: String? = null,
val isPublic: Boolean = true,
val timestamp: Instant = Clock.System.now(),
)
fun GameProfile.setTextures(textures: MinecraftTexturesPayloadKt) {
val json = Firmament.json.encodeToString(textures)
val encoded = java.util.Base64.getEncoder().encodeToString(json.encodeToByteArray())
properties.put(propertyTextures, Property(propertyTextures, encoded))
}
private val propertyTextures = "textures"
fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) {
assert(this.item == Items.PLAYER_HEAD)
val gameProfile = GameProfile(uuid, "LameGuy123")
gameProfile.properties.put(propertyTextures, Property(propertyTextures, encodedData.padToValidBase64()))
this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
}
val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1")
fun createSkullItem(uuid: UUID, url: String) = ItemStack(Items.PLAYER_HEAD)
.also { it.setSkullOwner(uuid, url) }
fun ItemStack.setSkullOwner(uuid: UUID, url: String) {
assert(this.item == Items.PLAYER_HEAD)
val gameProfile = GameProfile(uuid, "nea89")
gameProfile.setTextures(
MinecraftTexturesPayloadKt(
textures = mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)),
profileId = uuid,
profileName = "nea89",
)
)
this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile))
}
fun decodeProfileTextureProperty(property: Property): MinecraftTexturesPayloadKt? {
assertTrueOr(property.name == propertyTextures) { return null }
return try {
var encodedF: String = property.value
while (encodedF.length % 4 != 0 && encodedF.last() == '=') {
encodedF = encodedF.substring(0, encodedF.length - 1)
}
val json = java.util.Base64.getDecoder().decode(encodedF).decodeToString()
Firmament.json.decodeFromString<MinecraftTexturesPayloadKt>(json)
} catch (e: Exception) {
// Malformed profile data
if (Firmament.DEBUG)
e.printStackTrace()
null
}
}