style: MessageUtils 도입 - 전체 채팅 스타일 개선
- MessageUtils 유틸리티 추가 (청록색 기본 + 흰색 강조) - 모든 명령어 및 GUI에 통일된 메시지 스타일 적용 - 수정 파일: SpawnCommand, NicknameCommand, CoordinateCommand, HeadCommand, PlayerCommand, ProtectFarmlandCommand, ChatCommand, TeleportGui, CoordinateGui, ChatEvents
This commit is contained in:
parent
d0d8d0650f
commit
ee66dddd99
11 changed files with 395 additions and 415 deletions
|
|
@ -2,11 +2,10 @@ package com.beemer.essentials.command
|
||||||
|
|
||||||
import com.beemer.essentials.config.ChatConfig
|
import com.beemer.essentials.config.ChatConfig
|
||||||
import com.beemer.essentials.util.ChatUtils
|
import com.beemer.essentials.util.ChatUtils
|
||||||
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException
|
import com.mojang.brigadier.exceptions.CommandSyntaxException
|
||||||
import net.minecraft.ChatFormatting
|
|
||||||
import net.minecraft.commands.CommandSourceStack
|
import net.minecraft.commands.CommandSourceStack
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
@ -31,11 +30,7 @@ object ChatCommand {
|
||||||
|
|
||||||
private fun hasPermissionOrSend(player: ServerPlayer?, requiredLevel: Int = 2): Boolean {
|
private fun hasPermissionOrSend(player: ServerPlayer?, requiredLevel: Int = 2): Boolean {
|
||||||
if (player != null && !player.hasPermissions(requiredLevel)) {
|
if (player != null && !player.hasPermissions(requiredLevel)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "해당 명령어를 실행할 권한이 없습니다.")
|
||||||
Component.literal("해당 명령어를 실행할 권한이 없습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
@ -51,14 +46,14 @@ object ChatCommand {
|
||||||
|
|
||||||
ChatConfig.loadConfig()
|
ChatConfig.loadConfig()
|
||||||
|
|
||||||
val success =
|
if (player != null) {
|
||||||
Component.literal("채팅 형식을 새로고침했습니다.").withStyle {
|
MessageUtils.sendSuccess(player, "채팅 형식을 새로고침했습니다.")
|
||||||
it.withColor(ChatFormatting.GOLD)
|
} else {
|
||||||
}
|
context.source.sendSuccess(
|
||||||
|
{ MessageUtils.success("채팅 형식을 새로고침했습니다.") },
|
||||||
if (player == null)
|
false
|
||||||
context.source.sendSuccess({ success }, false)
|
)
|
||||||
else player.sendSystemMessage(success)
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
@ -81,9 +76,7 @@ object ChatCommand {
|
||||||
ChatUtils.clearChatForAll(allPlayers)
|
ChatUtils.clearChatForAll(allPlayers)
|
||||||
|
|
||||||
server.playerList.broadcastSystemMessage(
|
server.playerList.broadcastSystemMessage(
|
||||||
Component.literal("\u00A0\u00A0채팅창을 비웠습니다.").withStyle {
|
MessageUtils.info("채팅창을 비웠습니다."),
|
||||||
it.withColor(ChatFormatting.AQUA)
|
|
||||||
},
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import com.beemer.essentials.data.Location
|
||||||
import com.beemer.essentials.gui.Menu
|
import com.beemer.essentials.gui.Menu
|
||||||
import com.beemer.essentials.gui.createPageContainer
|
import com.beemer.essentials.gui.createPageContainer
|
||||||
import com.beemer.essentials.util.DimensionUtils
|
import com.beemer.essentials.util.DimensionUtils
|
||||||
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType
|
import com.mojang.brigadier.arguments.StringArgumentType
|
||||||
import net.minecraft.ChatFormatting
|
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
@ -19,7 +19,7 @@ import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
object CoordinateCommand {
|
object CoordinateCommand {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onRegisterCommands(event: RegisterCommandsEvent) {
|
fun onRegisterCommands(event: RegisterCommandsEvent) {
|
||||||
// /좌표 - GUI 열기 (페이지 0부터 시작)
|
// /좌표 - GUI 열기
|
||||||
event.dispatcher.register(
|
event.dispatcher.register(
|
||||||
Commands.literal("좌표").executes { context ->
|
Commands.literal("좌표").executes { context ->
|
||||||
val player = context.source.playerOrException as ServerPlayer
|
val player = context.source.playerOrException as ServerPlayer
|
||||||
|
|
@ -28,7 +28,7 @@ object CoordinateCommand {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// /좌표이동 <장소> - 바로 이동
|
// /좌표이동 <장소>
|
||||||
event.dispatcher.register(
|
event.dispatcher.register(
|
||||||
Commands.literal("좌표이동")
|
Commands.literal("좌표이동")
|
||||||
.then(
|
.then(
|
||||||
|
|
@ -70,16 +70,9 @@ object CoordinateCommand {
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CoordinateConfig.isExist(name)) {
|
if (CoordinateConfig.isExist(name)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(
|
||||||
Component.literal(
|
player,
|
||||||
"$name 좌표가 이미 존재합니다."
|
"{$name} 좌표가 이미 존재합니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.RED
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return@executes 0
|
return@executes 0
|
||||||
}
|
}
|
||||||
|
|
@ -116,16 +109,9 @@ object CoordinateCommand {
|
||||||
)
|
)
|
||||||
|
|
||||||
CoordinateConfig.addCoordinate(coordinate)
|
CoordinateConfig.addCoordinate(coordinate)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(
|
||||||
Component.literal(
|
player,
|
||||||
"$name 좌표를 추가했습니다."
|
"{$name} 좌표를 추가했습니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.GOLD
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
@ -155,31 +141,17 @@ object CoordinateCommand {
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!CoordinateConfig.isExist(name)) {
|
if (!CoordinateConfig.isExist(name)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(
|
||||||
Component.literal(
|
player,
|
||||||
"$name 좌표가 존재하지 않습니다."
|
"{$name} 좌표가 존재하지 않습니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.RED
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return@executes 0
|
return@executes 0
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordinateConfig.removeCoordinate(name)
|
CoordinateConfig.removeCoordinate(name)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(
|
||||||
Component.literal(
|
player,
|
||||||
"$name 좌표를 제거했습니다."
|
"{$name} 좌표를 제거했습니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.GOLD
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
@ -207,21 +179,13 @@ object CoordinateCommand {
|
||||||
private fun teleportToCoordinate(player: ServerPlayer, name: String): Int {
|
private fun teleportToCoordinate(player: ServerPlayer, name: String): Int {
|
||||||
val coord = CoordinateConfig.getCoordinate(name)
|
val coord = CoordinateConfig.getCoordinate(name)
|
||||||
if (coord == null) {
|
if (coord == null) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "{$name} 좌표가 존재하지 않습니다.")
|
||||||
Component.literal("$name 좌표가 존재하지 않습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val level = DimensionUtils.getLevelById(player.server, coord.dimension)
|
val level = DimensionUtils.getLevelById(player.server, coord.dimension)
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "존재하지 않는 차원입니다.")
|
||||||
Component.literal("존재하지 않는 차원입니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,11 +208,7 @@ object CoordinateCommand {
|
||||||
)
|
)
|
||||||
|
|
||||||
player.teleportTo(level, coord.x, coord.y, coord.z, player.yRot, player.xRot)
|
player.teleportTo(level, coord.x, coord.y, coord.z, player.yRot, player.xRot)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "{$name}(으)로 이동했습니다.")
|
||||||
Component.literal("$name (으)로 이동했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.beemer.essentials.command
|
||||||
|
|
||||||
import com.beemer.essentials.config.PlayerConfig
|
import com.beemer.essentials.config.PlayerConfig
|
||||||
import com.beemer.essentials.nickname.NicknameDataStore
|
import com.beemer.essentials.nickname.NicknameDataStore
|
||||||
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType
|
import com.mojang.brigadier.arguments.StringArgumentType
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
@ -30,8 +31,6 @@ object HeadCommand {
|
||||||
StringArgumentType.greedyString()
|
StringArgumentType.greedyString()
|
||||||
)
|
)
|
||||||
.suggests { _, builder ->
|
.suggests { _, builder ->
|
||||||
// 서버에 접속한 적 있는 플레이어만 제안
|
|
||||||
// 닉네임이 있으면 닉네임, 없으면 원래 이름
|
|
||||||
val suggestions =
|
val suggestions =
|
||||||
mutableListOf<String>()
|
mutableListOf<String>()
|
||||||
PlayerConfig.getAllPlayers()
|
PlayerConfig.getAllPlayers()
|
||||||
|
|
@ -93,11 +92,7 @@ object HeadCommand {
|
||||||
|
|
||||||
// 3. 서버에 접속한 적 없는 플레이어면 거부
|
// 3. 서버에 접속한 적 없는 플레이어면 거부
|
||||||
if (targetUuid == null || !PlayerConfig.isKnownPlayer(targetUuid)) {
|
if (targetUuid == null || !PlayerConfig.isKnownPlayer(targetUuid)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "해당 플레이어는 서버에 접속한 적이 없습니다.")
|
||||||
Component.literal("해당 플레이어는 서버에 접속한 적이 없습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,21 +125,13 @@ object HeadCommand {
|
||||||
val added = player.inventory.add(headItem)
|
val added = player.inventory.add(headItem)
|
||||||
|
|
||||||
if (added) {
|
if (added) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "{$displayName}의 머리가 지급되었습니다.")
|
||||||
Component.literal(displayName)
|
|
||||||
.withStyle { it.withColor(ChatFormatting.GREEN) }
|
|
||||||
.append(
|
|
||||||
Component.literal("의 머리가 지급되었습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
// 인벤토리가 가득 찬 경우 바닥에 드랍
|
// 인벤토리가 가득 찬 경우 바닥에 드랍
|
||||||
player.drop(headItem, false)
|
player.drop(headItem, false)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendWarning(
|
||||||
Component.literal("인벤토리가 가득 차서 ${displayName}의 머리를 바닥에 떨어뜨렸습니다.")
|
player,
|
||||||
.withStyle { it.withColor(ChatFormatting.YELLOW) }
|
"인벤토리가 가득 차서 {$displayName}의 머리를 바닥에 떨어뜨렸습니다."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,8 @@ package com.beemer.essentials.command
|
||||||
import com.beemer.essentials.config.PlayerConfig
|
import com.beemer.essentials.config.PlayerConfig
|
||||||
import com.beemer.essentials.util.CommandUtils
|
import com.beemer.essentials.util.CommandUtils
|
||||||
import com.beemer.essentials.util.DimensionUtils
|
import com.beemer.essentials.util.DimensionUtils
|
||||||
import net.minecraft.ChatFormatting
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
||||||
|
|
@ -23,16 +22,9 @@ object PlayerCommand {
|
||||||
val lastLocation =
|
val lastLocation =
|
||||||
info?.lastLocation
|
info?.lastLocation
|
||||||
?: run {
|
?: run {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(
|
||||||
Component.literal(
|
player,
|
||||||
"이전 위치가 존재하지 않습니다."
|
"이전 위치가 존재하지 않습니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.RED
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return@executes 0
|
return@executes 0
|
||||||
}
|
}
|
||||||
|
|
@ -43,16 +35,9 @@ object PlayerCommand {
|
||||||
lastLocation.dimension
|
lastLocation.dimension
|
||||||
)
|
)
|
||||||
?: run {
|
?: run {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(
|
||||||
Component.literal(
|
player,
|
||||||
"존재하지 않는 차원입니다."
|
"존재하지 않는 차원입니다."
|
||||||
)
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(
|
|
||||||
ChatFormatting
|
|
||||||
.RED
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
return@executes 0
|
return@executes 0
|
||||||
}
|
}
|
||||||
|
|
@ -65,11 +50,7 @@ object PlayerCommand {
|
||||||
player.yRot,
|
player.yRot,
|
||||||
player.xRot
|
player.xRot
|
||||||
)
|
)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "이전 위치로 이동했습니다.")
|
||||||
Component.literal("이전 위치로 이동했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@ package com.beemer.essentials.command
|
||||||
|
|
||||||
import com.beemer.essentials.config.ProtectFarmlandConfig
|
import com.beemer.essentials.config.ProtectFarmlandConfig
|
||||||
import com.beemer.essentials.util.CommandUtils
|
import com.beemer.essentials.util.CommandUtils
|
||||||
import net.minecraft.ChatFormatting
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
||||||
|
|
@ -19,22 +18,9 @@ object ProtectFarmlandCommand {
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
val enabled = ProtectFarmlandConfig.toggle()
|
val enabled = ProtectFarmlandConfig.toggle()
|
||||||
|
val status = if (enabled) "활성화" else "비활성화"
|
||||||
|
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "밭 보호를 {$status}했습니다.")
|
||||||
Component.literal("밭 보호를 ")
|
|
||||||
.withStyle { it.withColor(ChatFormatting.GOLD) }
|
|
||||||
.append(
|
|
||||||
Component.literal(if (enabled) "활성화" else "비활성화")
|
|
||||||
.withStyle {
|
|
||||||
it.withColor(ChatFormatting.DARK_GREEN)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
Component.literal("했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,116 +5,129 @@ import com.beemer.essentials.config.SpawnConfig
|
||||||
import com.beemer.essentials.data.Location
|
import com.beemer.essentials.data.Location
|
||||||
import com.beemer.essentials.util.CommandUtils
|
import com.beemer.essentials.util.CommandUtils
|
||||||
import com.beemer.essentials.util.DimensionUtils
|
import com.beemer.essentials.util.DimensionUtils
|
||||||
import net.minecraft.ChatFormatting
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
||||||
object SpawnCommand {
|
object SpawnCommand {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
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 =
|
val player =
|
||||||
CommandUtils.getPlayerOrSendFailure(context.source)
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
val exactPos = player.position()
|
val exactPos = player.position()
|
||||||
val blockPos = player.blockPosition()
|
val blockPos = player.blockPosition()
|
||||||
val dimensionId = player.level().dimension().location().toString()
|
val dimension =
|
||||||
val biomeId =
|
player.level().dimension().location().toString()
|
||||||
player.level()
|
val biome =
|
||||||
.getBiome(blockPos)
|
player.level()
|
||||||
.unwrapKey()
|
.getBiome(blockPos)
|
||||||
.map { it.location().toString() }
|
.unwrapKey()
|
||||||
.orElse("minecraft:plains")
|
.map { it.location().toString() }
|
||||||
|
.orElse("minecraft:plains")
|
||||||
|
|
||||||
val location =
|
val location =
|
||||||
Location(
|
Location(
|
||||||
dimension = dimensionId,
|
dimension = dimension,
|
||||||
biome = biomeId,
|
biome = biome,
|
||||||
x = exactPos.x,
|
x = exactPos.x,
|
||||||
y = exactPos.y,
|
y = exactPos.y,
|
||||||
z = exactPos.z
|
z = exactPos.z
|
||||||
)
|
)
|
||||||
|
|
||||||
SpawnConfig.setCustomSpawn(location)
|
SpawnConfig.setCustomSpawn(location)
|
||||||
|
MessageUtils.sendSuccess(player, "스폰 지점이 현재 위치로 설정되었습니다.")
|
||||||
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 =
|
val player =
|
||||||
CommandUtils.getPlayerOrSendFailure(context.source)
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
?: return@executes 0
|
?: 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 exactPos = player.position()
|
val exactPos = player.position()
|
||||||
val blockPos = player.blockPosition()
|
val blockPos = player.blockPosition()
|
||||||
val currentDimension =
|
val currentDimension =
|
||||||
player.level().dimension().location().toString()
|
player.level()
|
||||||
val currentBiome =
|
.dimension()
|
||||||
player.level()
|
.location()
|
||||||
.getBiome(blockPos)
|
.toString()
|
||||||
.unwrapKey()
|
val currentBiome =
|
||||||
.map { it.location().toString() }
|
player.level()
|
||||||
.orElse("minecraft:plains")
|
.getBiome(blockPos)
|
||||||
|
.unwrapKey()
|
||||||
|
.map {
|
||||||
|
it.location()
|
||||||
|
.toString()
|
||||||
|
}
|
||||||
|
.orElse("minecraft:plains")
|
||||||
|
|
||||||
val currentLocation =
|
val currentLocation =
|
||||||
Location(
|
Location(
|
||||||
dimension = currentDimension,
|
dimension =
|
||||||
biome = currentBiome,
|
currentDimension,
|
||||||
x = exactPos.x,
|
biome = currentBiome,
|
||||||
y = exactPos.y,
|
x = exactPos.x,
|
||||||
z = exactPos.z
|
y = exactPos.y,
|
||||||
)
|
z = exactPos.z
|
||||||
|
)
|
||||||
|
|
||||||
PlayerConfig.recordLastLocation(player, currentLocation)
|
PlayerConfig.recordLastLocation(
|
||||||
player.teleportTo(l, t.x, t.y, t.z, player.yRot, player.xRot)
|
player,
|
||||||
player.sendSystemMessage(
|
currentLocation
|
||||||
Component.literal("스폰으로 이동했습니다.").withStyle {
|
)
|
||||||
it.withColor(ChatFormatting.GOLD)
|
player.teleportTo(
|
||||||
|
l,
|
||||||
|
t.x,
|
||||||
|
t.y,
|
||||||
|
t.z,
|
||||||
|
player.yRot,
|
||||||
|
player.xRot
|
||||||
|
)
|
||||||
|
MessageUtils.sendSuccess(
|
||||||
|
player,
|
||||||
|
"스폰으로 이동했습니다."
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
1
|
||||||
}
|
|
||||||
}
|
|
||||||
1
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
listOf("delspawn", "스폰삭제").forEach { command ->
|
|
||||||
event.dispatcher.register(
|
|
||||||
Commands.literal(command).executes { context ->
|
|
||||||
val player =
|
|
||||||
CommandUtils.getPlayerOrSendFailure(context.source)
|
|
||||||
?: return@executes 0
|
|
||||||
|
|
||||||
SpawnConfig.removeCustomSpawn()
|
|
||||||
player.sendSystemMessage(
|
|
||||||
Component.literal("스폰 지점이 기본 스폰 지점으로 변경되었습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
1
|
}
|
||||||
}
|
|
||||||
)
|
listOf("delspawn", "스폰삭제").forEach { command ->
|
||||||
|
event.dispatcher.register(
|
||||||
|
Commands.literal(command).executes { context ->
|
||||||
|
val player =
|
||||||
|
CommandUtils.getPlayerOrSendFailure(context.source)
|
||||||
|
?: return@executes 0
|
||||||
|
|
||||||
|
SpawnConfig.removeCustomSpawn()
|
||||||
|
MessageUtils.sendInfo(player, "스폰 지점이 기본 스폰 지점으로 변경되었습니다.")
|
||||||
|
1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.beemer.essentials.event
|
package com.beemer.essentials.event
|
||||||
|
|
||||||
import com.beemer.essentials.util.ChatUtils
|
import com.beemer.essentials.util.ChatUtils
|
||||||
import net.minecraft.network.chat.Component
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.ServerChatEvent
|
import net.neoforged.neoforge.event.ServerChatEvent
|
||||||
|
|
@ -12,13 +12,11 @@ object ChatEvents {
|
||||||
val player = event.player as ServerPlayer
|
val player = event.player as ServerPlayer
|
||||||
val raw = event.rawText
|
val raw = event.rawText
|
||||||
|
|
||||||
if (raw.startsWith("/"))
|
if (raw.startsWith("/")) return
|
||||||
return
|
|
||||||
|
|
||||||
if (ChatUtils.hasIllegalCharacter(raw)) {
|
if (ChatUtils.hasIllegalCharacter(raw)) {
|
||||||
event.isCanceled = true
|
event.isCanceled = true
|
||||||
player.sendSystemMessage(Component.literal("채팅에 허용되지 않는 문자가 포함되어 있습니다.")
|
MessageUtils.sendError(player, "채팅에 허용되지 않는 문자가 포함되어 있습니다.")
|
||||||
.withStyle { it.withColor(net.minecraft.ChatFormatting.RED) })
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,4 +24,4 @@ object ChatEvents {
|
||||||
|
|
||||||
event.isCanceled = true
|
event.isCanceled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import com.beemer.essentials.config.CoordinateConfig
|
||||||
import com.beemer.essentials.config.PlayerConfig
|
import com.beemer.essentials.config.PlayerConfig
|
||||||
import com.beemer.essentials.data.Location
|
import com.beemer.essentials.data.Location
|
||||||
import com.beemer.essentials.nickname.NicknameDataStore
|
import com.beemer.essentials.nickname.NicknameDataStore
|
||||||
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import com.beemer.essentials.util.TranslationUtils.translateBiome
|
import com.beemer.essentials.util.TranslationUtils.translateBiome
|
||||||
import com.beemer.essentials.util.TranslationUtils.translateDimension
|
import com.beemer.essentials.util.TranslationUtils.translateDimension
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
@ -109,6 +110,7 @@ class Menu(
|
||||||
val x = tag.getDouble("x")
|
val x = tag.getDouble("x")
|
||||||
val y = tag.getDouble("y")
|
val y = tag.getDouble("y")
|
||||||
val z = tag.getDouble("z")
|
val z = tag.getDouble("z")
|
||||||
|
val coordName = tag.getString("name")
|
||||||
val dimension =
|
val dimension =
|
||||||
ResourceLocation.tryParse(tag.getString("dimension"))?.let {
|
ResourceLocation.tryParse(tag.getString("dimension"))?.let {
|
||||||
ResourceKey.create(Registries.DIMENSION, it)
|
ResourceKey.create(Registries.DIMENSION, it)
|
||||||
|
|
@ -135,15 +137,7 @@ class Menu(
|
||||||
)
|
)
|
||||||
|
|
||||||
player.teleportTo(level, x, y, z, player.yRot, player.xRot)
|
player.teleportTo(level, x, y, z, player.yRot, player.xRot)
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "{$coordName}(으)로 이동했습니다.")
|
||||||
Component.literal(tag.getString("name"))
|
|
||||||
.withStyle { it.withColor(ChatFormatting.DARK_GREEN) }
|
|
||||||
.append(
|
|
||||||
Component.literal("(으)로 이동했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
player.closeContainer()
|
player.closeContainer()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import com.beemer.essentials.config.PlayerConfig
|
||||||
import com.beemer.essentials.data.Location
|
import com.beemer.essentials.data.Location
|
||||||
import com.beemer.essentials.data.Player
|
import com.beemer.essentials.data.Player
|
||||||
import com.beemer.essentials.nickname.NicknameDataStore
|
import com.beemer.essentials.nickname.NicknameDataStore
|
||||||
import net.minecraft.ChatFormatting
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.Container
|
import net.minecraft.world.Container
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
|
@ -21,140 +20,127 @@ class TeleportGui(
|
||||||
val container: Container,
|
val container: Container,
|
||||||
val viewer: ServerPlayer
|
val viewer: ServerPlayer
|
||||||
) : AbstractContainerMenu(MenuType.GENERIC_9x3, syncId) {
|
) : AbstractContainerMenu(MenuType.GENERIC_9x3, syncId) {
|
||||||
companion object {
|
companion object {
|
||||||
const val CONTAINER_COLUMNS = 9
|
const val CONTAINER_COLUMNS = 9
|
||||||
const val CONTAINER_ROWS = 3
|
const val CONTAINER_ROWS = 3
|
||||||
const val CONTAINER_SIZE = CONTAINER_COLUMNS * CONTAINER_ROWS
|
const val CONTAINER_SIZE = CONTAINER_COLUMNS * CONTAINER_ROWS
|
||||||
|
|
||||||
const val SLOT_SIZE = 18
|
const val SLOT_SIZE = 18
|
||||||
const val LEFT_PADDING = 8
|
const val LEFT_PADDING = 8
|
||||||
const val TOP_PADDING = 18
|
const val TOP_PADDING = 18
|
||||||
|
|
||||||
const val PLAYER_INV_TOP = 86
|
const val PLAYER_INV_TOP = 86
|
||||||
const val HOTBAR_Y = 144
|
const val HOTBAR_Y = 144
|
||||||
}
|
|
||||||
|
|
||||||
private val targetPlayers =
|
|
||||||
viewer.server
|
|
||||||
.playerList
|
|
||||||
.players
|
|
||||||
.filterIsInstance<ServerPlayer>()
|
|
||||||
.filter { it.uuid != viewer.uuid }
|
|
||||||
.map { it.uuid }
|
|
||||||
|
|
||||||
init {
|
|
||||||
for (i in 0 until CONTAINER_SIZE) {
|
|
||||||
val x = LEFT_PADDING + (i % CONTAINER_COLUMNS) * SLOT_SIZE
|
|
||||||
val y = TOP_PADDING + (i / CONTAINER_COLUMNS) * SLOT_SIZE
|
|
||||||
addSlot(
|
|
||||||
object : Slot(container, i, x, y) {
|
|
||||||
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) {
|
private val targetPlayers =
|
||||||
for (col in 0 until 9) {
|
viewer.server
|
||||||
val index = col + row * 9 + 9
|
.playerList
|
||||||
val x = LEFT_PADDING + col * SLOT_SIZE
|
.players
|
||||||
val y = PLAYER_INV_TOP + row * SLOT_SIZE
|
.filterIsInstance<ServerPlayer>()
|
||||||
addSlot(Slot(playerInv, index, x, y))
|
.filter { it.uuid != viewer.uuid }
|
||||||
}
|
.map { it.uuid }
|
||||||
}
|
|
||||||
|
|
||||||
for (col in 0 until 9) {
|
init {
|
||||||
val x = LEFT_PADDING + col * SLOT_SIZE
|
for (i in 0 until CONTAINER_SIZE) {
|
||||||
val y = HOTBAR_Y
|
val x = LEFT_PADDING + (i % CONTAINER_COLUMNS) * SLOT_SIZE
|
||||||
addSlot(Slot(playerInv, col, x, y))
|
val y = TOP_PADDING + (i / CONTAINER_COLUMNS) * SLOT_SIZE
|
||||||
}
|
addSlot(
|
||||||
}
|
object : Slot(container, i, x, y) {
|
||||||
|
override fun mayPickup(
|
||||||
override fun clicked(
|
player: net.minecraft.world.entity.player.Player
|
||||||
slotId: Int,
|
): Boolean = false
|
||||||
button: Int,
|
override fun mayPlace(stack: ItemStack): Boolean = false
|
||||||
clickType: ClickType,
|
}
|
||||||
player: net.minecraft.world.entity.player.Player
|
|
||||||
) {
|
|
||||||
if (slotId in 0 until CONTAINER_SIZE && player is ServerPlayer) {
|
|
||||||
val currentTargetPlayer =
|
|
||||||
targetPlayers.getOrNull(slotId)?.let { player.server.playerList.getPlayer(it) }
|
|
||||||
|
|
||||||
if (currentTargetPlayer != null && player.uuid != currentTargetPlayer.uuid) {
|
|
||||||
val prevPos = player.blockPosition()
|
|
||||||
val prevDimension = player.level().dimension().location().toString()
|
|
||||||
val prevBiome =
|
|
||||||
player.level()
|
|
||||||
.getBiome(prevPos)
|
|
||||||
.unwrapKey()
|
|
||||||
.map { it.location().toString() }
|
|
||||||
.orElse("minecraft:plains")
|
|
||||||
val previousLocation =
|
|
||||||
Location(
|
|
||||||
dimension = prevDimension,
|
|
||||||
biome = prevBiome,
|
|
||||||
x = prevPos.x.toDouble(),
|
|
||||||
y = prevPos.y.toDouble(),
|
|
||||||
z = prevPos.z.toDouble()
|
|
||||||
)
|
)
|
||||||
PlayerConfig.recordLastLocation(player, previousLocation)
|
}
|
||||||
|
|
||||||
val targetLevel = currentTargetPlayer.serverLevel()
|
for (row in 0 until 3) {
|
||||||
|
for (col in 0 until 9) {
|
||||||
player.teleportTo(
|
val index = col + row * 9 + 9
|
||||||
targetLevel,
|
val x = LEFT_PADDING + col * SLOT_SIZE
|
||||||
currentTargetPlayer.x,
|
val y = PLAYER_INV_TOP + row * SLOT_SIZE
|
||||||
currentTargetPlayer.y,
|
addSlot(Slot(playerInv, index, x, y))
|
||||||
currentTargetPlayer.z,
|
|
||||||
currentTargetPlayer.yRot,
|
|
||||||
currentTargetPlayer.xRot
|
|
||||||
)
|
|
||||||
|
|
||||||
// 닉네임이 있으면 닉네임 사용
|
|
||||||
val targetName =
|
|
||||||
NicknameDataStore.getNickname(currentTargetPlayer.uuid)
|
|
||||||
?: currentTargetPlayer.gameProfile.name
|
|
||||||
val playerName =
|
|
||||||
NicknameDataStore.getNickname(player.uuid) ?: player.gameProfile.name
|
|
||||||
|
|
||||||
player.sendSystemMessage(
|
|
||||||
Component.literal(targetName)
|
|
||||||
.withStyle { it.withColor(ChatFormatting.AQUA) }
|
|
||||||
.append(
|
|
||||||
Component.literal("님에게 텔레포트 했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
currentTargetPlayer.sendSystemMessage(
|
|
||||||
Component.literal(playerName)
|
|
||||||
.withStyle { it.withColor(ChatFormatting.AQUA) }
|
|
||||||
.append(
|
|
||||||
Component.literal("님이 당신에게 텔레포트 했습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
player.sendSystemMessage(
|
|
||||||
Component.literal("해당 플레이어는 현재 오프라인입니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
player.closeContainer()
|
for (col in 0 until 9) {
|
||||||
return
|
val x = LEFT_PADDING + col * SLOT_SIZE
|
||||||
|
val y = HOTBAR_Y
|
||||||
|
addSlot(Slot(playerInv, col, x, y))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.clicked(slotId, button, clickType, player)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stillValid(player: net.minecraft.world.entity.player.Player): Boolean = true
|
override fun clicked(
|
||||||
|
slotId: Int,
|
||||||
|
button: Int,
|
||||||
|
clickType: ClickType,
|
||||||
|
player: net.minecraft.world.entity.player.Player
|
||||||
|
) {
|
||||||
|
if (slotId in 0 until CONTAINER_SIZE && player is ServerPlayer) {
|
||||||
|
val currentTargetPlayer =
|
||||||
|
targetPlayers.getOrNull(slotId)?.let {
|
||||||
|
player.server.playerList.getPlayer(it)
|
||||||
|
}
|
||||||
|
|
||||||
override fun quickMoveStack(
|
if (currentTargetPlayer != null && player.uuid != currentTargetPlayer.uuid
|
||||||
player: net.minecraft.world.entity.player.Player,
|
) {
|
||||||
index: Int
|
val prevPos = player.blockPosition()
|
||||||
): ItemStack = ItemStack.EMPTY
|
val prevDimension = player.level().dimension().location().toString()
|
||||||
|
val prevBiome =
|
||||||
|
player.level()
|
||||||
|
.getBiome(prevPos)
|
||||||
|
.unwrapKey()
|
||||||
|
.map { it.location().toString() }
|
||||||
|
.orElse("minecraft:plains")
|
||||||
|
val previousLocation =
|
||||||
|
Location(
|
||||||
|
dimension = prevDimension,
|
||||||
|
biome = prevBiome,
|
||||||
|
x = prevPos.x.toDouble(),
|
||||||
|
y = prevPos.y.toDouble(),
|
||||||
|
z = prevPos.z.toDouble()
|
||||||
|
)
|
||||||
|
PlayerConfig.recordLastLocation(player, previousLocation)
|
||||||
|
|
||||||
|
val targetLevel = currentTargetPlayer.serverLevel()
|
||||||
|
|
||||||
|
player.teleportTo(
|
||||||
|
targetLevel,
|
||||||
|
currentTargetPlayer.x,
|
||||||
|
currentTargetPlayer.y,
|
||||||
|
currentTargetPlayer.z,
|
||||||
|
currentTargetPlayer.yRot,
|
||||||
|
currentTargetPlayer.xRot
|
||||||
|
)
|
||||||
|
|
||||||
|
// 닉네임이 있으면 닉네임 사용
|
||||||
|
val targetName =
|
||||||
|
NicknameDataStore.getNickname(currentTargetPlayer.uuid)
|
||||||
|
?: currentTargetPlayer.gameProfile.name
|
||||||
|
val playerName =
|
||||||
|
NicknameDataStore.getNickname(player.uuid)
|
||||||
|
?: player.gameProfile.name
|
||||||
|
|
||||||
|
MessageUtils.sendSuccess(player, "{$targetName}님에게 텔레포트 했습니다.")
|
||||||
|
MessageUtils.sendInfo(
|
||||||
|
currentTargetPlayer,
|
||||||
|
"{$playerName}님이 당신에게 텔레포트 했습니다."
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
MessageUtils.sendError(player, "해당 플레이어는 현재 오프라인입니다.")
|
||||||
|
}
|
||||||
|
|
||||||
|
player.closeContainer()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
super.clicked(slotId, button, clickType, player)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
package com.beemer.essentials.nickname
|
package com.beemer.essentials.nickname
|
||||||
|
|
||||||
|
import com.beemer.essentials.util.MessageUtils
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType
|
import com.mojang.brigadier.arguments.StringArgumentType
|
||||||
import net.minecraft.ChatFormatting
|
|
||||||
import net.minecraft.commands.Commands
|
import net.minecraft.commands.Commands
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.neoforged.bus.api.SubscribeEvent
|
import net.neoforged.bus.api.SubscribeEvent
|
||||||
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
import net.neoforged.neoforge.event.RegisterCommandsEvent
|
||||||
|
|
@ -29,7 +28,6 @@ object NicknameCommand {
|
||||||
.entity as?
|
.entity as?
|
||||||
ServerPlayer
|
ServerPlayer
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
val nickname =
|
val nickname =
|
||||||
StringArgumentType
|
StringArgumentType
|
||||||
.getString(
|
.getString(
|
||||||
|
|
@ -46,7 +44,6 @@ object NicknameCommand {
|
||||||
val player =
|
val player =
|
||||||
context.source.entity as? ServerPlayer
|
context.source.entity as? ServerPlayer
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
executeReset(player)
|
executeReset(player)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -69,7 +66,6 @@ object NicknameCommand {
|
||||||
.entity as?
|
.entity as?
|
||||||
ServerPlayer
|
ServerPlayer
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
val nickname =
|
val nickname =
|
||||||
StringArgumentType
|
StringArgumentType
|
||||||
.getString(
|
.getString(
|
||||||
|
|
@ -86,7 +82,6 @@ object NicknameCommand {
|
||||||
val player =
|
val player =
|
||||||
context.source.entity as? ServerPlayer
|
context.source.entity as? ServerPlayer
|
||||||
?: return@executes 0
|
?: return@executes 0
|
||||||
|
|
||||||
executeReset(player)
|
executeReset(player)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -96,65 +91,34 @@ object NicknameCommand {
|
||||||
private fun executeSet(player: ServerPlayer, nickname: String): Int {
|
private fun executeSet(player: ServerPlayer, nickname: String): Int {
|
||||||
// 유효성 검사: 길이
|
// 유효성 검사: 길이
|
||||||
if (nickname.length < 2 || nickname.length > 16) {
|
if (nickname.length < 2 || nickname.length > 16) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "닉네임은 2~16자 사이여야 합니다.")
|
||||||
Component.literal("닉네임은 2~16자 사이여야 합니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 유효성 검사: 중복
|
// 유효성 검사: 중복
|
||||||
if (NicknameDataStore.isNicknameTaken(nickname, player.uuid)) {
|
if (NicknameDataStore.isNicknameTaken(nickname, player.uuid)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "이미 사용 중인 닉네임입니다.")
|
||||||
Component.literal("이미 사용 중인 닉네임입니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// 닉네임 저장 및 적용 (gameProfile.name = 실제 마인크래프트 이름)
|
// 닉네임 저장 및 적용
|
||||||
NicknameDataStore.setNickname(player.uuid, player.gameProfile.name, nickname)
|
NicknameDataStore.setNickname(player.uuid, player.gameProfile.name, nickname)
|
||||||
NicknameManager.applyNickname(player, nickname)
|
NicknameManager.applyNickname(player, nickname)
|
||||||
|
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "닉네임이 {$nickname}(으)로 변경되었습니다.")
|
||||||
Component.literal("닉네임이 ")
|
|
||||||
.withStyle { it.withColor(ChatFormatting.GOLD) }
|
|
||||||
.append(
|
|
||||||
Component.literal(nickname).withStyle {
|
|
||||||
it.withColor(ChatFormatting.AQUA)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.append(
|
|
||||||
Component.literal("(으)로 변경되었습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun executeReset(player: ServerPlayer): Int {
|
private fun executeReset(player: ServerPlayer): Int {
|
||||||
if (!NicknameDataStore.hasNickname(player.uuid)) {
|
if (!NicknameDataStore.hasNickname(player.uuid)) {
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendError(player, "설정된 닉네임이 없습니다.")
|
||||||
Component.literal("설정된 닉네임이 없습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.RED)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
NicknameDataStore.removeNickname(player.uuid)
|
NicknameDataStore.removeNickname(player.uuid)
|
||||||
NicknameManager.removeNickname(player)
|
NicknameManager.removeNickname(player)
|
||||||
|
|
||||||
player.sendSystemMessage(
|
MessageUtils.sendSuccess(player, "닉네임이 초기화되었습니다.")
|
||||||
Component.literal("닉네임이 초기화되었습니다.").withStyle {
|
|
||||||
it.withColor(ChatFormatting.GOLD)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
package com.beemer.essentials.util
|
||||||
|
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.network.chat.MutableComponent
|
||||||
|
import net.minecraft.network.chat.Style
|
||||||
|
import net.minecraft.network.chat.TextColor
|
||||||
|
import net.minecraft.server.level.ServerPlayer
|
||||||
|
|
||||||
|
/** 메시지 스타일 유틸리티 기본 텍스트: 밝은 청록색 (#A8D8D8) 강조 텍스트: 흰색 (#FFFFFF) */
|
||||||
|
object MessageUtils {
|
||||||
|
|
||||||
|
// 기본 색상 (더 밝게)
|
||||||
|
private const val BASE_COLOR = 0xA8D8D8 // 밝은 청록색 (기본 텍스트)
|
||||||
|
private const val ACCENT_COLOR = 0xFFFFFF // 흰색 (강조)
|
||||||
|
private const val ERROR_COLOR = 0xFF8888 // 밝은 빨간색 (오류)
|
||||||
|
private const val WARNING_COLOR = 0xFFE066 // 밝은 노란색 (경고)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 기본 스타일 메시지 생성
|
||||||
|
* @param text 텍스트 (강조 부분은 {중괄호}로 감싸기) 예: "스폰으로 이동했습니다." 또는 "{비머}님에게 텔레포트 요청을 보냈습니다."
|
||||||
|
*/
|
||||||
|
fun styled(text: String): MutableComponent {
|
||||||
|
return parseStyledText(text, BASE_COLOR, ACCENT_COLOR)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 성공 메시지 (아이콘 없이 기본 스타일) */
|
||||||
|
fun success(text: String): MutableComponent {
|
||||||
|
return styled(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 정보 메시지 (아이콘 없이 기본 스타일) */
|
||||||
|
fun info(text: String): MutableComponent {
|
||||||
|
return styled(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 오류 메시지 (빨간색 스타일) */
|
||||||
|
fun error(text: String): MutableComponent {
|
||||||
|
return parseStyledText(text, ERROR_COLOR, ACCENT_COLOR)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 경고 메시지 (노란색 스타일) */
|
||||||
|
fun warning(text: String): MutableComponent {
|
||||||
|
return parseStyledText(text, WARNING_COLOR, ACCENT_COLOR)
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 플레이어에게 직접 전송 ===
|
||||||
|
|
||||||
|
fun sendSuccess(player: ServerPlayer, text: String) {
|
||||||
|
player.sendSystemMessage(success(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendInfo(player: ServerPlayer, text: String) {
|
||||||
|
player.sendSystemMessage(info(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendError(player: ServerPlayer, text: String) {
|
||||||
|
player.sendSystemMessage(error(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendWarning(player: ServerPlayer, text: String) {
|
||||||
|
player.sendSystemMessage(warning(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 스타일 텍스트 파싱 {중괄호} 안의 텍스트는 강조 색상으로 표시 */
|
||||||
|
private fun parseStyledText(text: String, baseColor: Int, accentColor: Int): MutableComponent {
|
||||||
|
val result: MutableComponent = Component.empty()
|
||||||
|
var i = 0
|
||||||
|
val sb = StringBuilder()
|
||||||
|
|
||||||
|
while (i < text.length) {
|
||||||
|
when {
|
||||||
|
text[i] == '{' -> {
|
||||||
|
// 이전 텍스트 추가 (기본 색상)
|
||||||
|
if (sb.isNotEmpty()) {
|
||||||
|
result.append(
|
||||||
|
Component.literal(sb.toString())
|
||||||
|
.withStyle(
|
||||||
|
Style.EMPTY.withColor(TextColor.fromRgb(baseColor))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
sb.clear()
|
||||||
|
}
|
||||||
|
// 강조 텍스트 찾기
|
||||||
|
val endIdx = text.indexOf('}', i)
|
||||||
|
if (endIdx != -1) {
|
||||||
|
val accentText = text.substring(i + 1, endIdx)
|
||||||
|
result.append(
|
||||||
|
Component.literal(accentText)
|
||||||
|
.withStyle(
|
||||||
|
Style.EMPTY.withColor(
|
||||||
|
TextColor.fromRgb(accentColor)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
i = endIdx + 1
|
||||||
|
} else {
|
||||||
|
sb.append(text[i])
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
sb.append(text[i])
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 남은 텍스트 추가
|
||||||
|
if (sb.isNotEmpty()) {
|
||||||
|
result.append(
|
||||||
|
Component.literal(sb.toString())
|
||||||
|
.withStyle(Style.EMPTY.withColor(TextColor.fromRgb(baseColor)))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue