머리 명령어 추가
This commit is contained in:
parent
727769a170
commit
e4337b9e12
7 changed files with 312 additions and 99 deletions
|
|
@ -31,5 +31,6 @@ class Essentials(modEventBus: IEventBus) {
|
||||||
NeoForge.EVENT_BUS.register(AntimobCommand)
|
NeoForge.EVENT_BUS.register(AntimobCommand)
|
||||||
NeoForge.EVENT_BUS.register(CoordinateCommand)
|
NeoForge.EVENT_BUS.register(CoordinateCommand)
|
||||||
NeoForge.EVENT_BUS.register(NicknameCommand)
|
NeoForge.EVENT_BUS.register(NicknameCommand)
|
||||||
|
NeoForge.EVENT_BUS.register(HeadCommand)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
package com.beemer.essentials.command
|
||||||
|
|
||||||
|
import com.beemer.essentials.config.PlayerConfig
|
||||||
|
import com.beemer.essentials.nickname.NicknameDataStore
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType
|
||||||
|
import java.util.Optional
|
||||||
|
import java.util.UUID
|
||||||
|
import net.minecraft.ChatFormatting
|
||||||
|
import net.minecraft.commands.Commands
|
||||||
|
import net.minecraft.commands.SharedSuggestionProvider
|
||||||
|
import net.minecraft.core.component.DataComponents
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import net.minecraft.world.item.component.ResolvableProfile
|
||||||
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
||||||
|
object HeadCommand {
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onRegisterCommands(event: RegisterCommandsEvent) {
|
||||||
|
// /머리 <플레이어> - 해당 플레이어 머리 아이템 지급
|
||||||
|
listOf("머리", "head").forEach { command ->
|
||||||
|
event.dispatcher.register(
|
||||||
|
Commands.literal(command)
|
||||||
|
.then(
|
||||||
|
Commands.argument(
|
||||||
|
"플레이어",
|
||||||
|
StringArgumentType.greedyString()
|
||||||
|
)
|
||||||
|
.suggests { _, builder ->
|
||||||
|
// 서버에 접속한 적 있는 플레이어만 제안
|
||||||
|
// 닉네임이 있으면 닉네임, 없으면 원래 이름
|
||||||
|
val suggestions =
|
||||||
|
mutableListOf<String>()
|
||||||
|
PlayerConfig.getAllPlayers()
|
||||||
|
.forEach { (uuid, name) ->
|
||||||
|
val nickname =
|
||||||
|
NicknameDataStore
|
||||||
|
.getNickname(
|
||||||
|
UUID.fromString(
|
||||||
|
uuid
|
||||||
|
)
|
||||||
|
)
|
||||||
|
suggestions.add(
|
||||||
|
nickname
|
||||||
|
?: name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
SharedSuggestionProvider.suggest(
|
||||||
|
suggestions,
|
||||||
|
builder
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.executes { context ->
|
||||||
|
val player =
|
||||||
|
context.source.entity as?
|
||||||
|
ServerPlayer
|
||||||
|
?: return@executes 0
|
||||||
|
val targetName =
|
||||||
|
StringArgumentType
|
||||||
|
.getString(
|
||||||
|
context,
|
||||||
|
"플레이어"
|
||||||
|
)
|
||||||
|
givePlayerHead(player, targetName)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.executes { context ->
|
||||||
|
// 인자 없이 실행 시 자신의 머리
|
||||||
|
val player =
|
||||||
|
context.source.entity as? ServerPlayer
|
||||||
|
?: return@executes 0
|
||||||
|
givePlayerHead(player, player.gameProfile.name)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givePlayerHead(player: ServerPlayer, targetName: String): Int {
|
||||||
|
// 1. 원래 이름으로 UUID 찾기
|
||||||
|
var targetUuid = PlayerConfig.getUuidByName(targetName)
|
||||||
|
var realName = targetName
|
||||||
|
|
||||||
|
// 2. 못 찾으면 닉네임으로 UUID 찾기
|
||||||
|
if (targetUuid == null) {
|
||||||
|
val uuidByNickname = NicknameDataStore.getUuidByNickname(targetName)
|
||||||
|
if (uuidByNickname != null) {
|
||||||
|
targetUuid = uuidByNickname.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 서버에 접속한 적 없는 플레이어면 거부
|
||||||
|
if (targetUuid == null || !PlayerConfig.isKnownPlayer(targetUuid)) {
|
||||||
|
player.sendSystemMessage(
|
||||||
|
Component.literal("해당 플레이어는 서버에 접속한 적이 없습니다.").withStyle {
|
||||||
|
it.withColor(ChatFormatting.RED)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 실제 마인크래프트 이름 가져오기
|
||||||
|
val allPlayers = PlayerConfig.getAllPlayers()
|
||||||
|
realName = allPlayers[targetUuid] ?: targetName
|
||||||
|
|
||||||
|
// 표시용 이름 (닉네임 우선)
|
||||||
|
val displayName =
|
||||||
|
NicknameDataStore.getNickname(UUID.fromString(targetUuid)) ?: realName
|
||||||
|
|
||||||
|
// 머리 아이템 생성
|
||||||
|
val headItem = ItemStack(Items.PLAYER_HEAD)
|
||||||
|
val resolvableProfile =
|
||||||
|
ResolvableProfile(
|
||||||
|
Optional.of(realName),
|
||||||
|
Optional.empty<UUID>(),
|
||||||
|
com.mojang.authlib.properties.PropertyMap()
|
||||||
|
)
|
||||||
|
|
||||||
|
headItem.set(DataComponents.PROFILE, resolvableProfile)
|
||||||
|
headItem.set(
|
||||||
|
DataComponents.CUSTOM_NAME,
|
||||||
|
Component.literal("${displayName}의 머리").withStyle {
|
||||||
|
it.withColor(ChatFormatting.GOLD)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 인벤토리에 추가
|
||||||
|
val added = player.inventory.add(headItem)
|
||||||
|
|
||||||
|
if (added) {
|
||||||
|
player.sendSystemMessage(
|
||||||
|
Component.literal(displayName)
|
||||||
|
.withStyle { it.withColor(ChatFormatting.GREEN) }
|
||||||
|
.append(
|
||||||
|
Component.literal("의 머리가 지급되었습니다.").withStyle {
|
||||||
|
it.withColor(ChatFormatting.GOLD)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// 인벤토리가 가득 찬 경우 바닥에 드랍
|
||||||
|
player.drop(headItem, false)
|
||||||
|
player.sendSystemMessage(
|
||||||
|
Component.literal("인벤토리가 가득 차서 ${displayName}의 머리를 바닥에 떨어뜨렸습니다.")
|
||||||
|
.withStyle { it.withColor(ChatFormatting.YELLOW) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,78 +16,105 @@ object SpawnCommand {
|
||||||
fun onRegisterCommands(event: RegisterCommandsEvent) {
|
fun onRegisterCommands(event: RegisterCommandsEvent) {
|
||||||
listOf("setspawn", "스폰설정").forEach { command ->
|
listOf("setspawn", "스폰설정").forEach { command ->
|
||||||
event.dispatcher.register(
|
event.dispatcher.register(
|
||||||
Commands.literal(command).executes { context ->
|
Commands.literal(command).executes { context ->
|
||||||
val player = CommandUtils.getPlayerOrSendFailure(context.source) ?: return@executes 0
|
val player =
|
||||||
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
|
?: return@executes 0
|
||||||
|
|
||||||
val playerLocation = player.blockPosition()
|
val exactPos = player.position()
|
||||||
val dimensionId = player.level().dimension().location().toString()
|
val blockPos = player.blockPosition()
|
||||||
val biomeId = player.level().getBiome(playerLocation)
|
val dimensionId = player.level().dimension().location().toString()
|
||||||
.unwrapKey()
|
val biomeId =
|
||||||
.map { it.location().toString() }
|
player.level()
|
||||||
.orElse("minecraft:plains")
|
.getBiome(blockPos)
|
||||||
|
.unwrapKey()
|
||||||
|
.map { it.location().toString() }
|
||||||
|
.orElse("minecraft:plains")
|
||||||
|
|
||||||
val location = Location(
|
val location =
|
||||||
dimension = dimensionId,
|
Location(
|
||||||
biome = biomeId,
|
dimension = dimensionId,
|
||||||
x = playerLocation.x.toDouble(),
|
biome = biomeId,
|
||||||
y = playerLocation.y.toDouble(),
|
x = exactPos.x,
|
||||||
z = playerLocation.z.toDouble()
|
y = exactPos.y,
|
||||||
)
|
z = exactPos.z
|
||||||
|
)
|
||||||
|
|
||||||
SpawnConfig.setCustomSpawn(location)
|
SpawnConfig.setCustomSpawn(location)
|
||||||
|
|
||||||
player.sendSystemMessage(Component.literal("스폰 지점이 현재 위치로 설정되었습니다.").withStyle { it.withColor(ChatFormatting.GOLD) })
|
player.sendSystemMessage(
|
||||||
1
|
Component.literal("스폰 지점이 현재 위치로 설정되었습니다.").withStyle {
|
||||||
}
|
it.withColor(ChatFormatting.GOLD)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
1
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf("spawn", "스폰", "넴주").forEach { command ->
|
listOf("spawn", "스폰", "넴주").forEach { command ->
|
||||||
event.dispatcher.register(
|
event.dispatcher.register(
|
||||||
Commands.literal(command).executes { context ->
|
Commands.literal(command).executes { context ->
|
||||||
val player = CommandUtils.getPlayerOrSendFailure(context.source) ?: return@executes 0
|
val player =
|
||||||
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
|
?: return@executes 0
|
||||||
|
|
||||||
val target = SpawnConfig.getCustomSpawn() ?: SpawnConfig.getDefaultSpawn()
|
val target = SpawnConfig.getCustomSpawn() ?: SpawnConfig.getDefaultSpawn()
|
||||||
|
|
||||||
target?.let { t ->
|
target?.let { t ->
|
||||||
val level = DimensionUtils.getLevelById(player.server, t.dimension)
|
val level = DimensionUtils.getLevelById(player.server, t.dimension)
|
||||||
|
|
||||||
level?.let { l ->
|
level?.let { l ->
|
||||||
val currentPos = player.blockPosition()
|
val exactPos = player.position()
|
||||||
val currentDimension = player.level().dimension().location().toString()
|
val blockPos = player.blockPosition()
|
||||||
val currentBiome = player.level().getBiome(currentPos)
|
val currentDimension =
|
||||||
.unwrapKey()
|
player.level().dimension().location().toString()
|
||||||
.map { it.location().toString() }
|
val currentBiome =
|
||||||
.orElse("minecraft:plains")
|
player.level()
|
||||||
|
.getBiome(blockPos)
|
||||||
|
.unwrapKey()
|
||||||
|
.map { it.location().toString() }
|
||||||
|
.orElse("minecraft:plains")
|
||||||
|
|
||||||
val currentLocation = Location(
|
val currentLocation =
|
||||||
dimension = currentDimension,
|
Location(
|
||||||
biome = currentBiome,
|
dimension = currentDimension,
|
||||||
x = currentPos.x.toDouble(),
|
biome = currentBiome,
|
||||||
y = currentPos.y.toDouble(),
|
x = exactPos.x,
|
||||||
z = currentPos.z.toDouble()
|
y = exactPos.y,
|
||||||
)
|
z = exactPos.z
|
||||||
|
)
|
||||||
|
|
||||||
PlayerConfig.recordLastLocation(player, currentLocation)
|
PlayerConfig.recordLastLocation(player, currentLocation)
|
||||||
player.teleportTo(l, t.x, t.y, t.z, player.yRot, player.xRot)
|
player.teleportTo(l, t.x, t.y, t.z, player.yRot, player.xRot)
|
||||||
player.sendSystemMessage(Component.literal("스폰으로 이동했습니다.").withStyle { it.withColor(ChatFormatting.GOLD) })
|
player.sendSystemMessage(
|
||||||
|
Component.literal("스폰으로 이동했습니다.").withStyle {
|
||||||
|
it.withColor(ChatFormatting.GOLD)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
|
||||||
}
|
}
|
||||||
1
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf("delspawn", "스폰삭제").forEach { command ->
|
listOf("delspawn", "스폰삭제").forEach { command ->
|
||||||
event.dispatcher.register(
|
event.dispatcher.register(
|
||||||
Commands.literal(command).executes { context ->
|
Commands.literal(command).executes { context ->
|
||||||
val player = CommandUtils.getPlayerOrSendFailure(context.source) ?: return@executes 0
|
val player =
|
||||||
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
|
?: return@executes 0
|
||||||
|
|
||||||
SpawnConfig.removeCustomSpawn()
|
SpawnConfig.removeCustomSpawn()
|
||||||
player.sendSystemMessage(Component.literal("스폰 지점이 기본 스폰 지점으로 변경되었습니다.").withStyle { it.withColor(ChatFormatting.GOLD) })
|
player.sendSystemMessage(
|
||||||
1
|
Component.literal("스폰 지점이 기본 스폰 지점으로 변경되었습니다.").withStyle {
|
||||||
}
|
it.withColor(ChatFormatting.GOLD)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
1
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,16 +71,9 @@ object CoordinateConfig {
|
||||||
val dimension = tag.getString("dimension")
|
val dimension = tag.getString("dimension")
|
||||||
val biome = tag.getString("biome")
|
val biome = tag.getString("biome")
|
||||||
|
|
||||||
// 하위 호환: Int로 저장된 경우 Double로 변환
|
val x = tag.getDouble("x")
|
||||||
val x =
|
val y = tag.getDouble("y")
|
||||||
if (tag.contains("x", 6)) tag.getDouble("x")
|
val z = tag.getDouble("z")
|
||||||
else tag.getInt("x").toDouble() + 0.5
|
|
||||||
val y =
|
|
||||||
if (tag.contains("y", 6)) tag.getDouble("y")
|
|
||||||
else tag.getInt("y").toDouble()
|
|
||||||
val z =
|
|
||||||
if (tag.contains("z", 6)) tag.getDouble("z")
|
|
||||||
else tag.getInt("z").toDouble() + 0.5
|
|
||||||
|
|
||||||
val creatorUuid =
|
val creatorUuid =
|
||||||
if (tag.contains("creatorUuid")) tag.getString("creatorUuid")
|
if (tag.contains("creatorUuid")) tag.getString("creatorUuid")
|
||||||
|
|
|
||||||
|
|
@ -142,4 +142,19 @@ object PlayerConfig {
|
||||||
val uuid = player.uuid.toString()
|
val uuid = player.uuid.toString()
|
||||||
return players[uuid]
|
return players[uuid]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 모든 저장된 플레이어 목록 (uuid -> name) */
|
||||||
|
fun getAllPlayers(): Map<String, String> {
|
||||||
|
return players.mapValues { it.value.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 이름으로 UUID 찾기 */
|
||||||
|
fun getUuidByName(name: String): String? {
|
||||||
|
return players.entries.find { it.value.name.equals(name, ignoreCase = true) }?.key
|
||||||
|
}
|
||||||
|
|
||||||
|
/** UUID가 저장된 플레이어인지 확인 */
|
||||||
|
fun isKnownPlayer(uuid: String): Boolean {
|
||||||
|
return players.containsKey(uuid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.beemer.essentials.gui
|
package com.beemer.essentials.gui
|
||||||
|
|
||||||
import com.beemer.essentials.config.AntimobConfig
|
import com.beemer.essentials.config.AntimobConfig
|
||||||
import com.mojang.authlib.GameProfile
|
|
||||||
import net.minecraft.ChatFormatting
|
import net.minecraft.ChatFormatting
|
||||||
import net.minecraft.core.component.DataComponents
|
import net.minecraft.core.component.DataComponents
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
|
|
@ -15,9 +14,13 @@ import net.minecraft.world.inventory.Slot
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.item.Items
|
import net.minecraft.world.item.Items
|
||||||
import net.minecraft.world.item.component.ResolvableProfile
|
import net.minecraft.world.item.component.ResolvableProfile
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class AntimobGui(syncId: Int, playerInv: Inventory, val container: Container, private val viewer: ServerPlayer) : AbstractContainerMenu(MenuType.GENERIC_9x2, syncId) {
|
class AntimobGui(
|
||||||
|
syncId: Int,
|
||||||
|
playerInv: Inventory,
|
||||||
|
val container: Container,
|
||||||
|
viewer: ServerPlayer
|
||||||
|
) : AbstractContainerMenu(MenuType.GENERIC_9x2, syncId) {
|
||||||
companion object {
|
companion object {
|
||||||
const val CONTAINER_COLUMNS = 9
|
const val CONTAINER_COLUMNS = 9
|
||||||
const val CONTAINER_ROWS = 2
|
const val CONTAINER_ROWS = 2
|
||||||
|
|
@ -38,10 +41,14 @@ class AntimobGui(syncId: Int, playerInv: Inventory, val container: Container, pr
|
||||||
for (i in 0 until CONTAINER_SIZE) {
|
for (i in 0 until CONTAINER_SIZE) {
|
||||||
val x = LEFT_PADDING + (i % CONTAINER_COLUMNS) * SLOT_SIZE
|
val x = LEFT_PADDING + (i % CONTAINER_COLUMNS) * SLOT_SIZE
|
||||||
val y = TOP_PADDING + (i / CONTAINER_COLUMNS) * SLOT_SIZE
|
val y = TOP_PADDING + (i / CONTAINER_COLUMNS) * SLOT_SIZE
|
||||||
addSlot(object : Slot(container, i, x, y) {
|
addSlot(
|
||||||
override fun mayPickup(player: net.minecraft.world.entity.player.Player): Boolean = false
|
object : Slot(container, i, x, y) {
|
||||||
override fun mayPlace(stack: ItemStack): Boolean = false
|
override fun mayPickup(
|
||||||
})
|
player: net.minecraft.world.entity.player.Player
|
||||||
|
): Boolean = false
|
||||||
|
override fun mayPlace(stack: ItemStack): Boolean = false
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (row in 0 until 3) {
|
for (row in 0 until 3) {
|
||||||
|
|
@ -62,7 +69,12 @@ class AntimobGui(syncId: Int, playerInv: Inventory, val container: Container, pr
|
||||||
refreshContainerContents()
|
refreshContainerContents()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clicked(slotId: Int, button: Int, clickType: ClickType, player: net.minecraft.world.entity.player.Player) {
|
override fun clicked(
|
||||||
|
slotId: Int,
|
||||||
|
button: Int,
|
||||||
|
clickType: ClickType,
|
||||||
|
player: net.minecraft.world.entity.player.Player
|
||||||
|
) {
|
||||||
if (player is ServerPlayer && slotId in 0 until CONTAINER_SIZE) {
|
if (player is ServerPlayer && slotId in 0 until CONTAINER_SIZE) {
|
||||||
if (glassSlotToMob.containsKey(slotId)) {
|
if (glassSlotToMob.containsKey(slotId)) {
|
||||||
val mob = glassSlotToMob[slotId] ?: return
|
val mob = glassSlotToMob[slotId] ?: return
|
||||||
|
|
@ -77,51 +89,55 @@ class AntimobGui(syncId: Int, playerInv: Inventory, val container: Container, pr
|
||||||
|
|
||||||
override fun stillValid(player: net.minecraft.world.entity.player.Player): Boolean = true
|
override fun stillValid(player: net.minecraft.world.entity.player.Player): Boolean = true
|
||||||
|
|
||||||
override fun quickMoveStack(player: net.minecraft.world.entity.player.Player, index: Int): ItemStack = ItemStack.EMPTY
|
override fun quickMoveStack(
|
||||||
|
player: net.minecraft.world.entity.player.Player,
|
||||||
|
index: Int
|
||||||
|
): ItemStack = ItemStack.EMPTY
|
||||||
|
|
||||||
private fun makeMobHead(mob: String, player: ServerPlayer): ItemStack {
|
private fun makeMobHead(mob: String): ItemStack {
|
||||||
val headItem = ItemStack(Items.PLAYER_HEAD)
|
val headItem = ItemStack(Items.PLAYER_HEAD)
|
||||||
|
|
||||||
val uuid = when (mob) {
|
// MHF_ 스킨 이름 사용 (네트워크 요청 없음)
|
||||||
"크리퍼" -> UUID.fromString("057b1c47-1321-4863-a6fe-8887f9ec265f")
|
val skinName =
|
||||||
"가스트" -> UUID.fromString("063085a6-797f-4785-be1a-21cd7580f752")
|
when (mob) {
|
||||||
"엔더맨" -> UUID.fromString("40ffb372-12f6-4678-b3f2-2176bf56dd4b")
|
"크리퍼" -> "MHF_Creeper"
|
||||||
else -> UUID.fromString("c06f8906-4c8a-4911-9c29-ea1dbd1aab82")
|
"가스트" -> "MHF_Ghast"
|
||||||
}
|
"엔더맨" -> "MHF_Enderman"
|
||||||
|
else -> "MHF_Steve"
|
||||||
|
}
|
||||||
|
|
||||||
val filledProfile: GameProfile = try {
|
val resolvableProfile =
|
||||||
player.server.sessionService.fetchProfile(uuid, true)?.profile ?: player.gameProfile
|
ResolvableProfile(
|
||||||
} catch (_: Exception) {
|
java.util.Optional.of(skinName),
|
||||||
player.gameProfile
|
java.util.Optional.empty<java.util.UUID>(),
|
||||||
}
|
com.mojang.authlib.properties.PropertyMap()
|
||||||
|
)
|
||||||
|
|
||||||
val resolvableProfile = try {
|
headItem.set(
|
||||||
ResolvableProfile(filledProfile)
|
DataComponents.CUSTOM_NAME,
|
||||||
} catch (_: NoSuchMethodError) {
|
Component.literal(mob).withStyle { it.withColor(ChatFormatting.YELLOW) }
|
||||||
val ctor = ResolvableProfile::class.java.getDeclaredConstructor(GameProfile::class.java)
|
)
|
||||||
ctor.isAccessible = true
|
|
||||||
ctor.newInstance(filledProfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
headItem.set(DataComponents.CUSTOM_NAME, Component.literal(mob).withStyle { it.withColor(ChatFormatting.YELLOW) })
|
|
||||||
headItem.set(DataComponents.PROFILE, resolvableProfile)
|
headItem.set(DataComponents.PROFILE, resolvableProfile)
|
||||||
return headItem
|
return headItem
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeToggleGlass(mob: String): ItemStack {
|
private fun makeToggleGlass(mob: String): ItemStack {
|
||||||
val enabled = AntimobConfig.get(mob)
|
val enabled = AntimobConfig.get(mob)
|
||||||
val glass = if (enabled) ItemStack(Items.GREEN_STAINED_GLASS_PANE) else ItemStack(Items.RED_STAINED_GLASS_PANE)
|
val glass =
|
||||||
|
if (enabled) ItemStack(Items.GREEN_STAINED_GLASS_PANE)
|
||||||
|
else ItemStack(Items.RED_STAINED_GLASS_PANE)
|
||||||
val statusText = if (enabled) "활성화" else "비활성화"
|
val statusText = if (enabled) "활성화" else "비활성화"
|
||||||
glass.set(DataComponents.CUSTOM_NAME, Component.literal(statusText).withStyle { it.withColor(if (enabled) ChatFormatting.GREEN else ChatFormatting.RED) })
|
glass.set(
|
||||||
|
DataComponents.CUSTOM_NAME,
|
||||||
|
Component.literal(statusText).withStyle {
|
||||||
|
it.withColor(if (enabled) ChatFormatting.GREEN else ChatFormatting.RED)
|
||||||
|
}
|
||||||
|
)
|
||||||
return glass
|
return glass
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshContainerContents() {
|
private fun refreshContainerContents() {
|
||||||
headSlotToMob.forEach { (slot, mob) ->
|
headSlotToMob.forEach { (slot, mob) -> container.setItem(slot, makeMobHead(mob)) }
|
||||||
container.setItem(slot, makeMobHead(mob, viewer))
|
glassSlotToMob.forEach { (slot, mob) -> container.setItem(slot, makeToggleGlass(mob)) }
|
||||||
}
|
|
||||||
glassSlotToMob.forEach { (slot, mob) ->
|
|
||||||
container.setItem(slot, makeToggleGlass(mob))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,4 +86,12 @@ object NicknameDataStore {
|
||||||
fun hasNickname(uuid: UUID): Boolean {
|
fun hasNickname(uuid: UUID): Boolean {
|
||||||
return nicknames.containsKey(uuid.toString())
|
return nicknames.containsKey(uuid.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 닉네임으로 UUID 찾기 */
|
||||||
|
fun getUuidByNickname(nickname: String): UUID? {
|
||||||
|
val target = nickname.trim()
|
||||||
|
if (target.isEmpty()) return null
|
||||||
|
val entry = nicknames.entries.find { it.value.equals(target, ignoreCase = true) }
|
||||||
|
return entry?.key?.let { UUID.fromString(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue