Skip to content

Commit

Permalink
Add custom player heads to the GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
Sytm committed Oct 7, 2023
1 parent 9fb4202 commit d95d423
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 59 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## [Unreleased]

### Added
- The GUI supports the usage of custom player heads

### Changed
- Partial update of chinese translations by [SnowCutieOwO](https://github.com/SnowCutieOwO)
- The default config has been updated to replace some items with custom player heads

## 4.2.0

### Added
Expand Down
16 changes: 16 additions & 0 deletions utils/src/main/kotlin/de/md5lukas/waypoints/util/SpigotHelper.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package de.md5lukas.waypoints.util

import de.md5lukas.commons.paper.editMeta
import java.net.URL
import java.util.*
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.SkullMeta
import org.bukkit.plugin.Plugin

fun parseLocationString(player: Player, input: String): Location? {
Expand Down Expand Up @@ -36,3 +41,14 @@ fun minecraftVersionAtLeast(plugin: Plugin, minor: Int, patch: Int = 0): Boolean
}
return parsedVersion[1] >= minor && parsedVersion[2] >= patch
}

fun createCustomPlayerHead(plugin: Plugin, textureId: String): ItemStack {
val profile = plugin.server.createProfile(UUID.randomUUID())

profile.setTextures(
profile.textures.also { it.skin = URL("https://textures.minecraft.net/texture/$textureId") })

val stack = ItemStack(Material.PLAYER_HEAD)
stack.editMeta<SkullMeta> { playerProfile = profile }
return stack
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import de.md5lukas.commons.paper.getStringNotNull
import de.md5lukas.konfig.Configurable
import de.md5lukas.konfig.ExportConfigurationSection
import de.md5lukas.konfig.SkipConfig
import de.md5lukas.waypoints.util.createCustomPlayerHead
import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin

@Configurable
class InventoryConfiguration {
Expand All @@ -16,25 +19,37 @@ class InventoryConfiguration {
private var rootConfig: ConfigurationSection
set(value) {
_rootConfig = value
materialCache.clear()
itemCache.clear()
}
get() = _rootConfig!!

private val materialCache = HashMap<String, Material>()
private val itemCache = HashMap<String, ItemStack>()

fun getMaterial(path: String): Material {
val cached = materialCache[path]
private val headPrefix = Material.PLAYER_HEAD.name + ":"

fun createNewStack(plugin: Plugin, path: String): ItemStack {
val cached = itemCache[path]
if (cached != null) {
return cached
return cached.clone()
}

val materialString = rootConfig.getStringNotNull(path)
val material =
Material.matchMaterial(materialString)
?: throw IllegalArgumentException("The material $materialString at $path is not valid")

materialCache[path] = material

return material
val stack =
if (materialString.startsWith(headPrefix)) {
try {
createCustomPlayerHead(plugin, materialString.substring(headPrefix.length))
} catch (t: Throwable) {
throw IllegalArgumentException("Invalid player head format at $path", t)
}
} else {
ItemStack(
Material.matchMaterial(materialString)
?: throw IllegalArgumentException(
"The material $materialString at $path is not valid"))
}

itemCache[path] = stack

return stack.clone()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,37 @@ class ItemTranslation(
private val rawDescription: String
get() = translationLoader[descriptionKey]

val material: Material
val rawStack: ItemStack
get() =
fixedMaterial
?: translationLoader.plugin.waypointsConfig.inventory.getMaterial(
key + if (appendItemSuffix) ".item" else "")
fixedMaterial?.let(::ItemStack)
?: translationLoader.plugin.waypointsConfig.inventory.createNewStack(
translationLoader.plugin,
key + if (appendItemSuffix) ".item" else "",
)

val item: ItemStack
get() = getItem()

fun getItem(vararg resolvers: TagResolver): ItemStack =
ItemStack(material).also {
it.itemMeta =
it.itemMeta!!.also { itemMeta ->
itemMeta.displayName(
translationLoader.itemMiniMessage.deserialize(rawDisplayName, *resolvers))
var discard = true // Remove leading blank lines
itemMeta.lore(
rawDescription.lineSequence().mapNotNullTo(mutableListOf()) { line ->
if (line.isNotBlank()) {
discard = false
}
if (discard) {
null
} else {
translationLoader.itemMiniMessage.deserialize(line, *resolvers)
}
})
}
fun getItem(vararg resolvers: TagResolver): ItemStack = getItem(null, *resolvers)

fun getItem(materialOverride: Material?, vararg resolvers: TagResolver): ItemStack =
(materialOverride?.let(::ItemStack) ?: rawStack).also {
it.editMeta { itemMeta ->
itemMeta.displayName(
translationLoader.itemMiniMessage.deserialize(rawDisplayName, *resolvers))
var discard = true // Remove leading blank lines
itemMeta.lore(
rawDescription.lineSequence().mapNotNullTo(mutableListOf()) { line ->
if (line.isNotBlank()) {
discard = false
}
if (discard) {
null
} else {
translationLoader.itemMiniMessage.deserialize(line, *resolvers)
}
})
}
}

override fun reset() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import de.md5lukas.waypoints.WaypointsPlugin
import de.md5lukas.waypoints.api.Waypoint
import org.bukkit.Location
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack

class WaypointTrackable(private val plugin: WaypointsPlugin, val waypoint: Waypoint) :
StaticTrackable {
Expand All @@ -28,8 +27,7 @@ class WaypointTrackable(private val plugin: WaypointsPlugin, val waypoint: Waypo
.withReplacements(*waypoint.getResolvers(player, translatedTarget))
}

override val hologramItem =
ItemStack(waypoint.material ?: plugin.apiExtensions.run { waypoint.getIconMaterial() })
override val hologramItem = plugin.apiExtensions.run { waypoint.getIconStack() }

override fun equals(other: Any?): Boolean {
return waypoint == (other as? WaypointTrackable)?.waypoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import de.md5lukas.waypoints.gui.SharedDisplayable
import de.md5lukas.waypoints.lang.InventoryTranslation
import net.kyori.adventure.text.Component
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack

Expand All @@ -42,7 +41,7 @@ class APIExtensions(private val plugin: WaypointsPlugin) {
Type.PRIVATE -> translations.WAYPOINT_ICON_PRIVATE
Type.PUBLIC -> translations.WAYPOINT_ICON_PUBLIC
Type.PERMISSION -> translations.WAYPOINT_ICON_PERMISSION
}.getItem(*getResolvers(player))
}.getItem(material, *getResolvers(player))

when (type) {
Type.DEATH -> null
Expand All @@ -51,8 +50,6 @@ class APIExtensions(private val plugin: WaypointsPlugin) {
Type.PERMISSION -> translations.WAYPOINT_ICON_PERMISSION_CUSTOM_DESCRIPTION
}?.let { stack.applyDescription(it, description) }

material?.also { stack.type = it }

return stack
}

Expand All @@ -77,14 +74,14 @@ class APIExtensions(private val plugin: WaypointsPlugin) {
},
)

fun Waypoint.getIconMaterial(): Material =
material
fun Waypoint.getIconStack(): ItemStack =
material?.let(::ItemStack)
?: when (type) {
Type.DEATH -> translations.WAYPOINT_ICON_DEATH
Type.PRIVATE -> translations.WAYPOINT_ICON_PRIVATE
Type.PUBLIC -> translations.WAYPOINT_ICON_PUBLIC
Type.PERMISSION -> translations.WAYPOINT_ICON_PERMISSION
}.material
}.rawStack

fun Waypoint.getHologramTranslations() =
when (type) {
Expand Down Expand Up @@ -142,6 +139,7 @@ class APIExtensions(private val plugin: WaypointsPlugin) {
Type.PERMISSION -> translations.FOLDER_ICON_PERMISSION
else -> throw IllegalStateException("An folder with the type $type should not exist")
}.getItem(
material,
"name" placeholder name,
"description" placeholder (description ?: ""),
"created_at" placeholder createdAt,
Expand All @@ -156,8 +154,6 @@ class APIExtensions(private val plugin: WaypointsPlugin) {
Type.PERMISSION -> translations.FOLDER_ICON_PERMISSION_CUSTOM_DESCRIPTION
}?.let { stack.applyDescription(it, description) }

material?.also { stack.type = it }

return stack
}

Expand Down
20 changes: 10 additions & 10 deletions waypoints/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ sounds:

inventory:
general:
previous: ARROW
next: ARROW
previous: "PLAYER_HEAD:bd69e06e5dadfd84e5f3d1c21063f2553b2fa945ee1d4d7152fdc5425bc12a9"
next: "PLAYER_HEAD:19bf3292e126a105b54eba713aa1b152d541a1d8938829c56364d178ed22bf"
back: BARRIER

background:
Expand All @@ -437,7 +437,7 @@ inventory:

overview:
cycleSort: HOPPER
settings: CRAFTING_TABLE
settings: "PLAYER_HEAD:e4d49bae95c790c3b1ff5b2f01052a714d6185481d5b1c85930b3f99d2321674"
deselect: MILK_BUCKET
setWaypoint: TORCH
createFolder: WRITABLE_BOOK
Expand Down Expand Up @@ -471,7 +471,7 @@ inventory:
deselect: MILK_BUCKET
delete:
item: LAVA_BUCKET
question: OAK_SIGN
question: "PLAYER_HEAD:badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a"
confirm: LAVA_BUCKET
cancel: WATER_BUCKET
rename: NAME_TAG
Expand All @@ -486,12 +486,12 @@ inventory:
make:
public:
item: ENCHANTED_BOOK
question: OAK_SIGN
question: "PLAYER_HEAD:badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a"
confirm: ENCHANTED_BOOK
cancel: BARRIER
permission:
item: ENCHANTED_BOOK
question: OAK_SIGN
question: "PLAYER_HEAD:badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a"
confirm: ENCHANTED_BOOK
cancel: BARRIER
changeMapIcon: FILLED_MAP
Expand All @@ -505,7 +505,7 @@ inventory:

delete:
item: LAVA_BUCKET
question: OAK_SIGN
question: "PLAYER_HEAD:badc048a7ce78f7dad72a07da27d85c0916881e5522eeed1e3daf217a38c1a"
confirm: LAVA_BUCKET
cancel: WATER_BUCKET
rename: NAME_TAG
Expand All @@ -515,14 +515,14 @@ inventory:
noFolder: MINECART

selectBeaconColor:
moveLeft: ARROW
moveRight: ARROW
moveLeft: "PLAYER_HEAD:8652e2b936ca8026bd28651d7c9f2819d2e923697734d18dfdb13550f8fdad5f"
moveRight: "PLAYER_HEAD:2a3b8f681daad8bf436cae8da3fe8131f62a162ab81af639c3e0644aa6abac2f"

confirm:
background: GRAY_STAINED_GLASS_PANE

playerList:
refresh: FISHING_ROD
refresh: "PLAYER_HEAD:e887cc388c8dcfcf1ba8aa5c3c102dce9cf7b1b63e786b34d4f1c3796d3e9d61"

tracking:
background: GRAY_STAINED_GLASS_PANE
Expand Down
2 changes: 0 additions & 2 deletions waypoints/src/main/resources/lang/en.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


prefix: "<aqua><bold>Waypoints <yellow><bold>><reset> "
scriptPrefix: "<aqua><bold>Waypoints<green>Script <yellow><bold>><reset> "

Expand Down

0 comments on commit d95d423

Please sign in to comment.