diff --git a/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt b/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt index dcd7285d0..79336d62f 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -13,10 +13,12 @@ package de.bixilon.minosoft.data.chat +import de.bixilon.kutil.string.WhitespaceUtil.trimWhitespaces import de.bixilon.minosoft.data.chat.sender.* import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import java.util.* object ChatUtil { @@ -33,4 +35,20 @@ object ChatUtil { } return PlayerEntityMessageSender(uuid, entity.name, entity) } + + fun validateChatMessage(connection: PlayConnection, message: String) { + if (message.isBlank()) { + throw IllegalArgumentException("Chat message can not be blank!") + } + if (ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX in message) { + throw IllegalArgumentException("Chat message must not contain formatting (${ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX}): $message") + } + if (message.length > connection.version.maxChatMessageSize) { + throw IllegalArgumentException("Message length (${message.length} can not exceed ${connection.version.maxChatMessageSize})") + } + } + + fun trimChatMessage(message: String): String { + return message.trimWhitespaces() + } } diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/ChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/ChatMessage.kt index 877764acb..3fa4ca84d 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/message/ChatMessage.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/ChatMessage.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -15,8 +15,13 @@ package de.bixilon.minosoft.data.chat.message import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.formatting.TextFormattable -interface ChatMessage { +interface ChatMessage : TextFormattable { val text: ChatComponent val type: ChatMessageType + + override fun toText(): Any? { + return text + } } diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/internal/DebugChatMessage.kt similarity index 58% rename from src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt rename to src/main/java/de/bixilon/minosoft/data/chat/message/internal/DebugChatMessage.kt index fd242295d..d3c26c345 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/internal/DebugChatMessage.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -10,14 +10,12 @@ * * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.modding.event.events -import de.bixilon.minosoft.data.chat.message.InternalChatMessage -import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent -import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +package de.bixilon.minosoft.data.chat.message.internal -@Deprecated("message receive event: InternalMessage") -class InternalMessageReceiveEvent( - connection: PlayConnection, - val message: InternalChatMessage, -) : PlayConnectionEvent(connection), CancelableEvent +import de.bixilon.minosoft.data.text.BaseComponent +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.formatting.color.ChatColors +import de.bixilon.minosoft.gui.rendering.RenderConstants + +class DebugChatMessage(message: ChatComponent) : InternalChatMessage(BaseComponent(RenderConstants.DEBUG_MESSAGES_PREFIX, ChatComponent.of(message).apply { this.setFallbackColor(ChatColors.BLUE) })) diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/internal/InternalChatMessage.kt similarity index 68% rename from src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt rename to src/main/java/de/bixilon/minosoft/data/chat/message/internal/InternalChatMessage.kt index b10eaf454..5d9372eb0 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/internal/InternalChatMessage.kt @@ -11,26 +11,31 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.data.chat.message +package de.bixilon.minosoft.data.chat.message.internal import de.bixilon.minosoft.data.chat.ChatTextPositions import de.bixilon.minosoft.data.chat.ChatUtil +import de.bixilon.minosoft.data.chat.message.ChatMessage import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.registries.chat.ChatParameter import de.bixilon.minosoft.data.registries.chat.TypeProperties import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft +import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.gui.rendering.RenderConstants -class InternalChatMessage( - override val text: ChatComponent, +open class InternalChatMessage( + val raw: ChatComponent, ) : ChatMessage { override val type: ChatMessageType get() = TYPE init { - text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) + raw.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) } + override val text: ChatComponent = BaseComponent(RenderConstants.INTERNAL_MESSAGES_PREFIX, raw) + companion object { - val TYPE = ChatMessageType(minosoft("internal"), TypeProperties("%s", listOf(ChatParameter.CONTENT), mapOf()), narration = null, position = ChatTextPositions.CHAT) + val TYPE = ChatMessageType(minosoft("internal_message"), TypeProperties("%s", listOf(ChatParameter.CONTENT), mapOf()), narration = null, position = ChatTextPositions.CHAT) } } diff --git a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt index 3aeb00c51..6962c2019 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -110,7 +110,7 @@ class BaseComponent : ChatComponent { } while (char != CharacterIterator.DONE) { - if (char != ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) { + if (char != ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) { currentText.append(char) char = iterator.next() continue @@ -156,7 +156,7 @@ class BaseComponent : ChatComponent { } json["text"]?.nullCast()?.let { - if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) != -1) { + if (it.indexOf(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) != -1) { this += ChatComponent.of(it, translator, parent, restrictedMode) parseExtra() return diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index 35f001350..b60f56f54 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -37,7 +37,7 @@ open class TextComponent( var clickEvent: ClickEvent? = null, var hoverEvent: HoverEvent? = null, ) : ChatComponent, TextStyle { - override var message: String = message.toString().replace(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR, '&') + override var message: String = message.toString().replace(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX, '&') override fun obfuscate(): TextComponent { formatting.add(PreChatFormattingCodes.OBFUSCATED); return this @@ -106,15 +106,15 @@ open class TextComponent( color?.let { val colorChar = ChatCode.FORMATTING_CODES_ID.indexOf(it) if (colorChar != -1) { - stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR).append(Integer.toHexString(colorChar)) + stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX).append(Integer.toHexString(colorChar)) } } for (formattingCode in this.formatting) { - stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) + stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX) stringBuilder.append(formattingCode.char) } stringBuilder.append(this.message) - stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR).append(PostChatFormattingCodes.RESET.char) // ToDo: This should not always be appended + stringBuilder.append(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX).append(PostChatFormattingCodes.RESET.char) // ToDo: This should not always be appended return stringBuilder.toString() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt index 719f2be15..ea6035036 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/ChatElement.kt @@ -20,6 +20,7 @@ import de.bixilon.minosoft.config.key.KeyActions import de.bixilon.minosoft.config.key.KeyBinding import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.data.chat.ChatTextPositions +import de.bixilon.minosoft.data.chat.message.internal.InternalChatMessage import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.font.Font @@ -33,8 +34,7 @@ import de.bixilon.minosoft.gui.rendering.gui.hud.elements.HUDBuilder import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes -import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.delegate.RenderingDelegate.observeRendering @@ -82,16 +82,15 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer), override fun init() { - connection.events.listen { + connection.events.listen { if (it.message.type.position == ChatTextPositions.HOTBAR) { return@listen } - DefaultThreadPool += { messages += it.message.text } - } - connection.events.listen { - if (!profile.chat.internal.hidden) { + if (it.message is InternalChatMessage && !profile.chat.internal.hidden) { + // message will be displayed in internal chat return@listen } + DefaultThreadPool += { messages += it.message.text } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/InternalChatElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/InternalChatElement.kt index a14b037c7..a2dc9dc9a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/InternalChatElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/chat/InternalChatElement.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -15,9 +15,10 @@ package de.bixilon.minosoft.gui.rendering.gui.hud.elements.chat import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kutil.concurrent.pool.DefaultThreadPool +import de.bixilon.minosoft.data.chat.message.internal.InternalChatMessage import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.elements.Element -import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.util.delegate.RenderingDelegate.observeRendering @@ -47,11 +48,11 @@ class InternalChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRen override fun init() { - connection.events.listen { - if (profile.chat.internal.hidden) { + connection.events.listen { + if (it.message !is InternalChatMessage || profile.chat.internal.hidden) { return@listen } - DefaultThreadPool += { messages += it.message.text } + DefaultThreadPool += { messages += it.message.raw } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarElement.kt index d1c14b337..27045fe93 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarElement.kt @@ -34,7 +34,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.left import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.right -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.delegate.RenderingDelegate.observeRendering @@ -178,7 +178,7 @@ class HotbarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedEl player::selectedHotbarSlot.observeRendering(this) { core.base.apply() } - connection.events.listen { + connection.events.listen { if (it.message.type.position != ChatTextPositions.HOTBAR) { return@listen } diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/CancelableEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/CancelableEvent.kt index aae608030..8c7a2c57b 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/CancelableEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/CancelableEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -14,6 +14,7 @@ package de.bixilon.minosoft.modding.event.events import de.bixilon.kutil.collections.CollectionUtil.synchronizedSetOf +@Deprecated("field") interface CancelableEvent { var cancelled: Boolean get() = CANCELLED_EVENTS.contains(this) diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageReceiveEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageEvent.kt similarity index 94% rename from src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageReceiveEvent.kt rename to src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageEvent.kt index 26af0601d..e65526ee6 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageReceiveEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -17,7 +17,7 @@ import de.bixilon.minosoft.modding.event.events.CancelableEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection -class ChatMessageReceiveEvent( +class ChatMessageEvent( connection: PlayConnection, val message: ChatMessage, ) : PlayConnectionEvent(connection), CancelableEvent diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt index 5d46cdd0d..e212381bc 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt @@ -45,7 +45,7 @@ import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.world.World import de.bixilon.minosoft.gui.eros.dialog.ErosErrorReport.Companion.report import de.bixilon.minosoft.gui.rendering.Rendering -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionCreateEvent import de.bixilon.minosoft.modding.event.events.loading.RegistriesLoadEvent import de.bixilon.minosoft.modding.event.listener.CallbackEventListener @@ -58,6 +58,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.channel.ConnectionCh import de.bixilon.minosoft.protocol.network.connection.play.channel.DefaultChannelHandlers import de.bixilon.minosoft.protocol.network.connection.play.settings.ClientSettingsManager import de.bixilon.minosoft.protocol.network.connection.play.tick.ConnectionTicker +import de.bixilon.minosoft.protocol.network.connection.play.util.ConnectionUtil import de.bixilon.minosoft.protocol.packets.c2s.handshaking.HandshakeC2SP import de.bixilon.minosoft.protocol.packets.c2s.login.StartC2SP import de.bixilon.minosoft.protocol.protocol.ProtocolStates @@ -155,7 +156,7 @@ class PlayConnection( CLI.connection = this } - events.register(CallbackEventListener.of { + events.register(CallbackEventListener.of { val additionalPrefix = when (it.message.type.position) { ChatTextPositions.SYSTEM -> "[SYSTEM] " ChatTextPositions.HOTBAR -> "[HOTBAR] " diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/ConnectionUtil.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt similarity index 69% rename from src/main/java/de/bixilon/minosoft/protocol/network/connection/play/ConnectionUtil.kt rename to src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt index 8ea7044f3..4a3686039 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/ConnectionUtil.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/util/ConnectionUtil.kt @@ -11,34 +11,31 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.protocol.network.connection.play +package de.bixilon.minosoft.protocol.network.connection.play.util import de.bixilon.kotlinglm.vec3.Vec3d -import de.bixilon.kutil.string.WhitespaceUtil.trimWhitespaces import de.bixilon.minosoft.commands.nodes.ChatNode import de.bixilon.minosoft.commands.stack.CommandStack import de.bixilon.minosoft.commands.util.CommandReader -import de.bixilon.minosoft.data.chat.message.InternalChatMessage +import de.bixilon.minosoft.data.chat.ChatUtil +import de.bixilon.minosoft.data.chat.message.internal.DebugChatMessage +import de.bixilon.minosoft.data.chat.message.internal.InternalChatMessage import de.bixilon.minosoft.data.chat.signature.Acknowledgement import de.bixilon.minosoft.data.chat.signature.signer.MessageSigner import de.bixilon.minosoft.data.entities.entities.player.local.HealthCondition -import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.world.time.WorldTime import de.bixilon.minosoft.data.world.weather.WorldWeather -import de.bixilon.minosoft.gui.rendering.RenderConstants import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY -import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.modding.event.events.chat.ChatMessageSendEvent import de.bixilon.minosoft.modding.event.events.container.ContainerCloseEvent import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork +import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.c2s.play.chat.ChatMessageC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.chat.CommandC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.chat.SignedChatMessageC2SP -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.logging.Log -import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType import java.security.PrivateKey import java.security.SecureRandom @@ -50,38 +47,23 @@ class ConnectionUtil( val signer = MessageSigner.forVersion(connection.version, connection) private val random = SecureRandom() - fun sendDebugMessage(message: Any) { - val component = BaseComponent(RenderConstants.DEBUG_MESSAGES_PREFIX, ChatComponent.of(message).apply { this.setFallbackColor(ChatColors.BLUE) }) - connection.events.fire(InternalMessageReceiveEvent(connection, InternalChatMessage(component))) - Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { component } + fun sendDebugMessage(raw: Any) { + val message = DebugChatMessage(ChatComponent.of(raw)) + connection.events.fire(ChatMessageEvent(connection, message)) } - fun sendInternal(message: Any) { - val component = ChatComponent.of(message) - val prefixed = BaseComponent(RenderConstants.INTERNAL_MESSAGES_PREFIX, component) - connection.events.fire(InternalMessageReceiveEvent(connection, InternalChatMessage(if (connection.profiles.gui.chat.internal.hidden) prefixed else component))) - Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { prefixed } + fun sendInternal(raw: Any) { + val message = InternalChatMessage(ChatComponent.of(raw)) + connection.events.fire(ChatMessageEvent(connection, message)) } fun typeChat(message: String) { ChatNode("", allowCLI = false).execute(CommandReader(message), CommandStack(connection)) } - private fun validateChatMessage(message: String) { - if (message.isBlank()) { - throw IllegalArgumentException("Chat message can not be blank!") - } - if (message.contains(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR)) { - throw IllegalArgumentException("Chat message must not contain chat formatting (${ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR}): $message") - } - if (message.length > connection.version.maxChatMessageSize) { - throw IllegalArgumentException("Message length (${message.length} can not exceed ${connection.version.maxChatMessageSize})") - } - } - fun sendChatMessage(message: String) { - val trimmed = message.trimWhitespaces() - validateChatMessage(trimmed) + val trimmed = ChatUtil.trimChatMessage(message) + ChatUtil.validateChatMessage(connection, message) if (connection.events.fire(ChatMessageSendEvent(connection, trimmed))) { return } @@ -113,10 +95,10 @@ class ConnectionUtil( if (!connection.version.requiresSignedChat || connection.profiles.connection.signature.sendCommandAsMessage) { return sendChatMessage(command) } - val trimmed = command.trimWhitespaces().removePrefix("/") - validateChatMessage(trimmed) + val trimmed = ChatUtil.trimChatMessage(command).removePrefix("/") + ChatUtil.validateChatMessage(connection, trimmed) if (stack.size == 0) { - throw IllegalArgumentException("Empty command stack! Did the command failed to parse?") + throw IllegalArgumentException("Empty command stack! Did the command fail to parse?") } val salt = SecureRandom().nextLong() val time = Instant.now() diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/ChatMessageS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/ChatMessageS2CP.kt index e8392553e..3067251c4 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/ChatMessageS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/ChatMessageS2CP.kt @@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.chat.message.SimpleChatMessage import de.bixilon.minosoft.data.chat.type.DefaultMessageTypes import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket @@ -64,7 +64,7 @@ class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } else { PlayerChatMessage(text, type, connection.getMessageSender(sender)) } - connection.events.fire(ChatMessageReceiveEvent(connection, message)) + connection.events.fire(ChatMessageEvent(connection, message)) } override fun log(reducedLog: Boolean) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/SignedChatMessageS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/SignedChatMessageS2CP.kt index 997b7299a..149605d90 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/SignedChatMessageS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/SignedChatMessageS2CP.kt @@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.chat.signature.verifyer.MessageVerifyUtil import de.bixilon.minosoft.data.registries.chat.ChatParameter import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.TextComponent -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket @@ -144,7 +144,7 @@ class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { return } } - connection.events.fire(ChatMessageReceiveEvent(connection, message)) + connection.events.fire(ChatMessageEvent(connection, message)) } override fun log(reducedLog: Boolean) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt index 8b760a093..59e7e7957 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt @@ -15,7 +15,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.chat import de.bixilon.minosoft.data.chat.message.FormattedChatMessage import de.bixilon.minosoft.data.registries.chat.ChatParameter import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket @@ -35,7 +35,7 @@ class UnsignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { override fun handle(connection: PlayConnection) { val message = FormattedChatMessage(connection, type, parameters) - connection.events.fire(ChatMessageReceiveEvent(connection, message)) + connection.events.fire(ChatMessageEvent(connection, message)) } override fun log(reducedLog: Boolean) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/title/HotbarTextS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/title/HotbarTextS2CP.kt index 07912e23d..e29d1f82e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/title/HotbarTextS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/title/HotbarTextS2CP.kt @@ -15,7 +15,7 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.title import de.bixilon.minosoft.data.chat.message.SimpleChatMessage import de.bixilon.minosoft.data.chat.type.DefaultMessageTypes -import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer @@ -34,6 +34,6 @@ class HotbarTextS2CP(buffer: PlayInByteBuffer) : TitleS2CP { override fun handle(connection: PlayConnection) { Log.log(LogMessageType.CHAT_IN) { "[HOTBAR] $text" } val message = SimpleChatMessage(text, connection.registries.messageType[DefaultMessageTypes.GAME]!!) - connection.events.fire(ChatMessageReceiveEvent(connection, message)) + connection.events.fire(ChatMessageEvent(connection, message)) } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java index d776b90b0..a8f0011d1 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/ProtocolDefinition.java @@ -30,7 +30,7 @@ public final class ProtocolDefinition { public static final int QUERY_PROTOCOL_VERSION_ID = -1; - public static final char TEXT_COMPONENT_SPECIAL_PREFIX_CHAR = '§'; + public static final char TEXT_COMPONENT_FORMATTING_PREFIX = '§'; public static final int AIR_BLOCK_ID = 0; diff --git a/src/main/java/de/bixilon/minosoft/util/json/ChatComponentColorSerializer.kt b/src/main/java/de/bixilon/minosoft/util/json/ChatComponentColorSerializer.kt index 46dca2443..2f197dc95 100644 --- a/src/main/java/de/bixilon/minosoft/util/json/ChatComponentColorSerializer.kt +++ b/src/main/java/de/bixilon/minosoft/util/json/ChatComponentColorSerializer.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -41,7 +41,7 @@ object ChatComponentColorSerializer : SimpleModule() { object Serializer : StdSerializer(ChatComponent::class.java) { override fun serialize(value: ChatComponent?, generator: JsonGenerator, provider: SerializerProvider?) { - generator.writeString(value?.legacyText?.removeSuffix(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR.toString() + PostChatFormattingCodes.RESET.char.toString())) + generator.writeString(value?.legacyText?.removeSuffix(ProtocolDefinition.TEXT_COMPONENT_FORMATTING_PREFIX.toString() + PostChatFormattingCodes.RESET.char.toString())) } } } diff --git a/src/main/java/de/bixilon/minosoft/util/logging/Log.kt b/src/main/java/de/bixilon/minosoft/util/logging/Log.kt index f0e455f55..6c3543316 100644 --- a/src/main/java/de/bixilon/minosoft/util/logging/Log.kt +++ b/src/main/java/de/bixilon/minosoft/util/logging/Log.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * Copyright (C) 2020-2023 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -18,6 +18,7 @@ import de.bixilon.minosoft.config.profile.profiles.other.OtherProfileSelectEvent import de.bixilon.minosoft.data.text.BaseComponent import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.TextComponent +import de.bixilon.minosoft.data.text.formatting.TextFormattable import de.bixilon.minosoft.modding.event.listener.CallbackEventListener import de.bixilon.minosoft.modding.event.master.GlobalEventMaster import de.bixilon.minosoft.terminal.RunConfiguration @@ -125,6 +126,7 @@ object Log { } val formattedMessage = when (message) { is ChatComponent -> message + is TextFormattable -> ChatComponent.of(message.toText()) is Throwable -> { val stringWriter = StringWriter() message.printStackTrace(PrintWriter(stringWriter))