diff --git a/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt b/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt new file mode 100644 index 000000000..a333c2bda --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt @@ -0,0 +1,36 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat + +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 java.util.* + +object ChatUtil { + val DEFAULT_CHAT_COLOR = ChatColors.WHITE + + fun PlayConnection.getMessageSender(uuid: UUID): MessageSender { + val entity = this.world.entities[uuid] + if (entity == null) { + val tab = tabList.tabListItemsByUUID[uuid] ?: return UnknownMessageSender(uuid) + return TabMessageSender(uuid, tab) + } + if (entity !is PlayerEntity) { + return InvalidSender(uuid) + } + return PlayerEntityMessageSender(uuid, entity.name, entity) + } +} 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 b6822fe80..877764acb 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 @@ -13,8 +13,10 @@ package de.bixilon.minosoft.data.chat.message +import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.text.ChatComponent interface ChatMessage { val text: ChatComponent + val type: ChatMessageType } diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt new file mode 100644 index 000000000..9a2e5b65d --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/InternalChatMessage.kt @@ -0,0 +1,37 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.message + +import de.bixilon.minosoft.data.chat.ChatTextPositions +import de.bixilon.minosoft.data.chat.ChatUtil +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.text.ChatComponent +import de.bixilon.minosoft.util.KUtil.minosoft + +class InternalChatMessage( + override val text: ChatComponent, +) : ChatMessage { + override val type: ChatMessageType get() = TYPE + + init { + text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) + } + + companion object { + + val TYPE = ChatMessageType(minosoft("internal"), TypeProperties("%s", listOf(ChatParameter.CONTENT), mapOf()), narration = null, position = ChatTextPositions.CHAT) + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerChatMessage.kt index c43ad2ff4..fa6b0be6b 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerChatMessage.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerChatMessage.kt @@ -13,12 +13,12 @@ package de.bixilon.minosoft.data.chat.message -import de.bixilon.minosoft.data.chat.type.DefaultMessageTypes +import de.bixilon.minosoft.data.chat.sender.MessageSender +import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.text.ChatComponent -import java.util.* open class PlayerChatMessage( text: ChatComponent, - type: DefaultMessageTypes, - val sender: UUID, -) : SimpleChatMessage(text, type) + type: ChatMessageType, + override val sender: MessageSender, +) : SimpleChatMessage(text, type), PlayerSentMessage diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerSentMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerSentMessage.kt new file mode 100644 index 000000000..2de6006ba --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/PlayerSentMessage.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.message + +import de.bixilon.minosoft.data.chat.sender.MessageSender + +interface PlayerSentMessage { + val sender: MessageSender +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt new file mode 100644 index 000000000..220d0cda4 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt @@ -0,0 +1,50 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.message + +import de.bixilon.minosoft.data.chat.ChatUtil +import de.bixilon.minosoft.data.chat.filter.Filter +import de.bixilon.minosoft.data.chat.sender.MessageSender +import de.bixilon.minosoft.data.language.lang.Language +import de.bixilon.minosoft.data.registries.chat.ChatMessageType +import de.bixilon.minosoft.data.registries.chat.ChatParameter +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import java.time.Instant + +class SignedChatMessage( + private val connection: PlayConnection, + val message: String, + override val type: ChatMessageType, + override val sender: MessageSender, + val parameters: Map, + val filter: Filter?, + val error: Exception?, + val sent: Instant, + val received: Instant, +) : ChatMessage, PlayerSentMessage { + override val text: ChatComponent + + init { + // ToDo: parent (formatting) + val data = type.chat.formatParameters(parameters) + text = if (connection.language.canTranslate(type.chat.translationKey.toResourceLocation())) { + connection.language.translate(type.chat.translationKey.toResourceLocation(), data = data) + } else { + Language.translate(type.chat.translationKey, data = data) + } + text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/SimpleChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/SimpleChatMessage.kt index 00ecd1691..c97c7974a 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/message/SimpleChatMessage.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/SimpleChatMessage.kt @@ -13,10 +13,15 @@ package de.bixilon.minosoft.data.chat.message -import de.bixilon.minosoft.data.chat.type.DefaultMessageTypes +import de.bixilon.minosoft.data.chat.ChatUtil +import de.bixilon.minosoft.data.registries.chat.ChatMessageType import de.bixilon.minosoft.data.text.ChatComponent open class SimpleChatMessage( override val text: ChatComponent, - val type: DefaultMessageTypes, -) : ChatMessage + override val type: ChatMessageType, +) : ChatMessage { + init { + text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR) + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/InvalidSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/InvalidSender.kt new file mode 100644 index 000000000..c6f488f17 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/InvalidSender.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import java.util.* + +class InvalidSender( + override val uuid: UUID, +) : MessageSender diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/MessageSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/MessageSender.kt new file mode 100644 index 000000000..86af62d3d --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/MessageSender.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import java.util.* + +interface MessageSender { + val uuid: UUID +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerEntityMessageSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerEntityMessageSender.kt new file mode 100644 index 000000000..651618550 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerEntityMessageSender.kt @@ -0,0 +1,23 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity +import java.util.* + +class PlayerEntityMessageSender( + uuid: UUID, + name: String, + val player: PlayerEntity, +) : PlayerMessageSender(uuid, name) diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerMessageSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerMessageSender.kt new file mode 100644 index 000000000..a3b31b183 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/PlayerMessageSender.kt @@ -0,0 +1,21 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import java.util.* + +abstract class PlayerMessageSender( + override val uuid: UUID, + val name: String, +) : MessageSender diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/TabMessageSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/TabMessageSender.kt new file mode 100644 index 000000000..e30900321 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/TabMessageSender.kt @@ -0,0 +1,23 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import de.bixilon.minosoft.data.entities.entities.player.tab.TabListItem +import java.util.* + +@Deprecated("Bad name") +class TabMessageSender( + uuid: UUID, + val tab: TabListItem, +) : PlayerMessageSender(uuid, tab.name) diff --git a/src/main/java/de/bixilon/minosoft/data/chat/sender/UnknownMessageSender.kt b/src/main/java/de/bixilon/minosoft/data/chat/sender/UnknownMessageSender.kt new file mode 100644 index 000000000..6eaffd27b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/sender/UnknownMessageSender.kt @@ -0,0 +1,18 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.sender + +import java.util.* + +class UnknownMessageSender(override val uuid: UUID) : MessageSender diff --git a/src/main/java/de/bixilon/minosoft/data/chat/signature/ChatSignatureProperties.kt b/src/main/java/de/bixilon/minosoft/data/chat/signature/ChatSignatureProperties.kt new file mode 100644 index 000000000..429b5a427 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/signature/ChatSignatureProperties.kt @@ -0,0 +1,18 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.signature + +object ChatSignatureProperties { + const val MESSAGE_TTL = 2 * 60 * 1000 // 2 Minutes +} diff --git a/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/InvalidSignatureError.kt b/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/InvalidSignatureError.kt new file mode 100644 index 000000000..bd8635230 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/InvalidSignatureError.kt @@ -0,0 +1,16 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.signature.errors + +class InvalidSignatureError : Exception("Signature does not match") diff --git a/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/MessageExpiredError.kt b/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/MessageExpiredError.kt new file mode 100644 index 000000000..b86c93f38 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/signature/errors/MessageExpiredError.kt @@ -0,0 +1,21 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.chat.signature.errors + +import java.time.Instant + +class MessageExpiredError( + val sent: Instant, + val received: Instant, +) : Exception("Message expired: Sent at $sent, but received to late at $received") diff --git a/src/main/java/de/bixilon/minosoft/data/language/lang/Language.kt b/src/main/java/de/bixilon/minosoft/data/language/lang/Language.kt index 662880ab6..5a4339534 100644 --- a/src/main/java/de/bixilon/minosoft/data/language/lang/Language.kt +++ b/src/main/java/de/bixilon/minosoft/data/language/lang/Language.kt @@ -25,52 +25,12 @@ class Language( ) : Translator { override fun canTranslate(key: ResourceLocation?): Boolean { - return data.containsKey(key?.namespace) + return data.containsKey(key?.path) } override fun translate(key: ResourceLocation?, parent: TextComponent?, vararg data: Any?): ChatComponent { val placeholder = this.data[key?.path] ?: return LanguageUtil.getFallbackTranslation(key, parent, data) - - val ret = BaseComponent() - - val arguments: MutableList = mutableListOf() - var splitPlaceholder: List = emptyList() - - // Bring arguments in correct oder - FORMATTER_ORDER_REGEX.findAll(placeholder).toList().let { - if (it.isEmpty()) { - // this is not the correct formatter - return@let - } - splitPlaceholder = placeholder.split(FORMATTER_ORDER_REGEX) - for (matchResult in it) { - // 2 groups: Full, index. We don't care about the full value, just skip it - val dataIndex = matchResult.groupValues[1].toInt() - 1 - if (dataIndex < 0 || dataIndex > data.size) { - arguments += null - continue - } - arguments += data[dataIndex] - } - } - - // check if other splitter already did the job for us - if (splitPlaceholder.isEmpty()) { - placeholder.split(FORMATTER_SPLIT_REGEX).let { - splitPlaceholder = it - arguments.addAll(data.toList()) - } - } - - // create base component - for ((index, part) in splitPlaceholder.withIndex()) { - ret += ChatComponent.of(part, this, parent) - if (index < data.size) { - ret += ChatComponent.of(arguments[index], this, parent) - } - } - - return ret + return Companion.translate(placeholder, parent, this, *data) } override fun toString(): String { @@ -80,5 +40,50 @@ class Language( companion object { private val FORMATTER_ORDER_REGEX = "%(\\w+)\\\$[sd]".toRegex() // %1$s fell from a high place private val FORMATTER_SPLIT_REGEX = "%[ds]".toRegex() // %s fell from a high place + + + fun translate(placeholder: String, parent: TextComponent? = null, translator: Translator? = null, vararg data: Any?): ChatComponent { + + val ret = BaseComponent() + + val arguments: MutableList = mutableListOf() + var splitPlaceholder: List = emptyList() + + // Bring arguments in correct oder + FORMATTER_ORDER_REGEX.findAll(placeholder).toList().let { + if (it.isEmpty()) { + // this is not the correct formatter + return@let + } + splitPlaceholder = placeholder.split(FORMATTER_ORDER_REGEX) + for (matchResult in it) { + // 2 groups: Full, index. We don't care about the full value, just skip it + val dataIndex = matchResult.groupValues[1].toInt() - 1 + if (dataIndex < 0 || dataIndex > data.size) { + arguments += null + continue + } + arguments += data[dataIndex] + } + } + + // check if other splitter already did the job for us + if (splitPlaceholder.isEmpty()) { + placeholder.split(FORMATTER_SPLIT_REGEX).let { + splitPlaceholder = it + arguments.addAll(data.toList()) + } + } + + // create base component + for ((index, part) in splitPlaceholder.withIndex()) { + ret += ChatComponent.of(part, translator, parent) + if (index < data.size) { + ret += ChatComponent.of(arguments[index], translator, parent) + } + } + + return ret + } } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/chat/ChatMessageType.kt b/src/main/java/de/bixilon/minosoft/data/registries/chat/ChatMessageType.kt index 53bf2cd00..830bf86f8 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/chat/ChatMessageType.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/chat/ChatMessageType.kt @@ -28,6 +28,10 @@ class ChatMessageType( val position: ChatTextPositions, ) : RegistryItem() { + override fun toString(): String { + return resourceLocation.toString() + } + companion object : ResourceLocationCodec { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): ChatMessageType { diff --git a/src/main/java/de/bixilon/minosoft/data/registries/chat/TypeProperties.kt b/src/main/java/de/bixilon/minosoft/data/registries/chat/TypeProperties.kt index 32b7e4e42..4c3a3fb2c 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/chat/TypeProperties.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/chat/TypeProperties.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.registries.chat import de.bixilon.kutil.json.JsonObject import de.bixilon.kutil.json.JsonUtil.asJsonList import de.bixilon.kutil.json.JsonUtil.asJsonObject +import de.bixilon.minosoft.data.text.ChatComponent class TypeProperties( val translationKey: String, @@ -23,6 +24,16 @@ class TypeProperties( val style: Map, ) { + fun formatParameters(parameters: Map): Array { + val output: MutableList = mutableListOf() + + for (parameter in this.parameters) { + output += parameters[parameter] ?: continue + } + + return output.toTypedArray() + } + companion object { fun deserialize(data: JsonObject): TypeProperties { 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 3e8b483db..67a9214b5 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 @@ -33,8 +33,8 @@ 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.ChatMessageReceiveEvent import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.util.KUtil.toResourceLocation @@ -82,16 +82,16 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer), override fun init() { connection.registerEvent(CallbackEventInvoker.of { - if (it.type.position == ChatTextPositions.HOTBAR) { + if (it.message.type.position == ChatTextPositions.HOTBAR) { return@of } - DefaultThreadPool += { messages += it.message } + DefaultThreadPool += { messages += it.message.text } }) connection.registerEvent(CallbackEventInvoker.of { if (!profile.chat.internal.hidden) { return@of } - DefaultThreadPool += { messages += it.message } + DefaultThreadPool += { messages += it.message.text } }) renderWindow.inputHandler.registerKeyCallback( 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 dd7feda72..dd370e7ef 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 @@ -51,7 +51,7 @@ class InternalChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRen if (profile.chat.internal.hidden) { return@of } - DefaultThreadPool += { messages += it.message } + DefaultThreadPool += { messages += it.message.text } }) } 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 5ec913ccd..021da0a9b 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 @@ -35,9 +35,9 @@ 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.ChatMessageReceiveEvent import de.bixilon.minosoft.modding.event.events.ExperienceChangeEvent import de.bixilon.minosoft.modding.event.events.SelectHotbarSlotEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.util.KUtil.toResourceLocation import java.lang.Integer.max @@ -179,7 +179,7 @@ class HotbarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedEl connection.registerEvent(CallbackEventInvoker.of { core.base.apply() }) connection.registerEvent(CallbackEventInvoker.of { - if (it.type.position != ChatTextPositions.HOTBAR) { + if (it.message.type.position != ChatTextPositions.HOTBAR) { return@of } hoverText.text = it.message diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageReceiveEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageReceiveEvent.kt deleted file mode 100644 index c556951aa..000000000 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageReceiveEvent.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020-2022 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. If not, see . - * - * 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.type.DefaultMessageTypes -import de.bixilon.minosoft.data.registries.chat.ChatMessageType -import de.bixilon.minosoft.data.text.ChatComponent -import de.bixilon.minosoft.modding.event.EventInitiators -import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent -import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection -import de.bixilon.minosoft.protocol.packets.s2c.play.chat.ChatMessageS2CP -import de.bixilon.minosoft.protocol.packets.s2c.play.chat.SignedChatMessageS2CP -import de.bixilon.minosoft.protocol.packets.s2c.play.title.HotbarTextS2CP -import java.util.* - -class ChatMessageReceiveEvent( - connection: PlayConnection, - initiator: EventInitiators, - val message: ChatComponent, - val type: ChatMessageType, - val sender: UUID?, -) : PlayConnectionEvent(connection, initiator), CancelableEvent { - - - constructor(connection: PlayConnection, packet: ChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message, packet.type, packet.sender) - - constructor(connection: PlayConnection, packet: HotbarTextS2CP) : this(connection, EventInitiators.SERVER, packet.text, connection.registries.messageTypeRegistry[DefaultMessageTypes.GAME]!!, null) - - constructor(connection: PlayConnection, packet: SignedChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message.body.text, connection.registries.messageTypeRegistry[DefaultMessageTypes.CHAT]!!, packet.message.header.sender) -} diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt index b0bce1b6b..b817449a0 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/InternalMessageReceiveEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * Copyright (C) 2020-2022 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. * @@ -12,12 +12,12 @@ */ package de.bixilon.minosoft.modding.event.events -import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.chat.message.InternalChatMessage import de.bixilon.minosoft.modding.event.EventInitiators import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection class InternalMessageReceiveEvent( connection: PlayConnection, - val message: ChatComponent, + val message: InternalChatMessage, ) : PlayConnectionEvent(connection, EventInitiators.CLIENT), CancelableEvent 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/ChatMessageReceiveEvent.kt new file mode 100644 index 000000000..c731b4867 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageReceiveEvent.kt @@ -0,0 +1,25 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ +package de.bixilon.minosoft.modding.event.events.chat + +import de.bixilon.minosoft.data.chat.message.ChatMessage +import de.bixilon.minosoft.modding.event.EventInitiators +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( + connection: PlayConnection, + initiator: EventInitiators, + val message: ChatMessage, +) : PlayConnectionEvent(connection, initiator), CancelableEvent diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageSendEvent.kt b/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageSendEvent.kt similarity index 87% rename from src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageSendEvent.kt rename to src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageSendEvent.kt index 5667d5e86..611ce2f0f 100644 --- a/src/main/java/de/bixilon/minosoft/modding/event/events/ChatMessageSendEvent.kt +++ b/src/main/java/de/bixilon/minosoft/modding/event/events/chat/ChatMessageSendEvent.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020 Moritz Zwerger + * Copyright (C) 2020-2022 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,9 +10,10 @@ * * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.modding.event.events +package de.bixilon.minosoft.modding.event.events.chat import de.bixilon.minosoft.modding.event.EventInitiators +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 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/ConnectionUtil.kt index 194bee6f1..a32569c44 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/ConnectionUtil.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.protocol.network.connection.play import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kutil.string.WhitespaceUtil.trimWhitespaces import de.bixilon.minosoft.commands.stack.CommandStack +import de.bixilon.minosoft.data.chat.message.InternalChatMessage import de.bixilon.minosoft.data.chat.signature.Acknowledgement import de.bixilon.minosoft.data.chat.signature.MessageChain import de.bixilon.minosoft.data.text.BaseComponent @@ -23,8 +24,8 @@ import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.data.text.formatting.color.ChatColors 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.ChatMessageSendEvent import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent +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.packets.c2s.play.chat.ChatMessageC2SP @@ -46,14 +47,14 @@ class ConnectionUtil( fun sendDebugMessage(message: Any) { val component = BaseComponent(RenderConstants.DEBUG_MESSAGES_PREFIX, ChatComponent.of(message).apply { this.setFallbackColor(ChatColors.BLUE) }) - connection.fireEvent(InternalMessageReceiveEvent(connection, component)) + connection.fireEvent(InternalMessageReceiveEvent(connection, InternalChatMessage(component))) Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { component } } fun sendInternal(message: Any) { val component = ChatComponent.of(message) val prefixed = BaseComponent(RenderConstants.INTERNAL_MESSAGES_PREFIX, component) - connection.fireEvent(InternalMessageReceiveEvent(connection, if (connection.profiles.gui.chat.internal.hidden) prefixed else component)) + connection.fireEvent(InternalMessageReceiveEvent(connection, InternalChatMessage(if (connection.profiles.gui.chat.internal.hidden) prefixed else component))) Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { prefixed } } 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 0aa11578d..944f0d7a3 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.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent import de.bixilon.minosoft.modding.event.events.loading.RegistriesLoadEvent import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.Connection @@ -151,12 +151,12 @@ class PlayConnection( } registerEvent(CallbackEventInvoker.of { - val additionalPrefix = when (it.type.position) { + val additionalPrefix = when (it.message.type.position) { ChatTextPositions.SYSTEM -> "[SYSTEM] " ChatTextPositions.HOTBAR -> "[HOTBAR] " else -> "" } - Log.log(LogMessageType.CHAT_IN, additionalPrefix = ChatComponent.of(additionalPrefix)) { it.message } + Log.log(LogMessageType.CHAT_IN, additionalPrefix = ChatComponent.of(additionalPrefix)) { it.message.text } }) } } 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 7bb47fa14..e8f2eda6c 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 @@ -12,10 +12,15 @@ */ package de.bixilon.minosoft.protocol.packets.s2c.play.chat +import de.bixilon.minosoft.data.chat.ChatUtil.getMessageSender +import de.bixilon.minosoft.data.chat.message.ChatMessage +import de.bixilon.minosoft.data.chat.message.PlayerChatMessage +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.ChatMessageReceiveEvent +import de.bixilon.minosoft.modding.event.EventInitiators +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent 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 @@ -29,7 +34,7 @@ import java.util.* @LoadPacket(threadSafe = false) class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { - val message: ChatComponent = buffer.readChatComponent() + val text: ChatComponent = buffer.readChatComponent() var type: ChatMessageType = buffer.connection.registries.messageTypeRegistry[DefaultMessageTypes.CHAT]!! private set var sender: UUID? = null @@ -48,17 +53,21 @@ class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } } } - message.setFallbackColor(ProtocolDefinition.DEFAULT_COLOR) + text.setFallbackColor(ProtocolDefinition.DEFAULT_COLOR) } override fun handle(connection: PlayConnection) { - val event = ChatMessageReceiveEvent(connection, this) - if (connection.fireEvent(event)) { - return + val type = if (overlay) connection.registries.messageTypeRegistry[DefaultMessageTypes.GAME]!! else type + val sender = sender + val message: ChatMessage = if (sender == null) { + SimpleChatMessage(text, type) + } else { + PlayerChatMessage(text, type, connection.getMessageSender(sender)) } + connection.fireEvent(ChatMessageReceiveEvent(connection, EventInitiators.SERVER, message)) } override fun log(reducedLog: Boolean) { - Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Chat message (message=\"$message\")" } + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Chat message (test=\"$text\", sender=$sender, overlay=$overlay)" } } } 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 616364777..365f73911 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 @@ -12,24 +12,105 @@ */ package de.bixilon.minosoft.protocol.packets.s2c.play.chat -import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent +import de.bixilon.minosoft.data.chat.ChatUtil.getMessageSender +import de.bixilon.minosoft.data.chat.filter.ChatFilter +import de.bixilon.minosoft.data.chat.filter.Filter +import de.bixilon.minosoft.data.chat.message.SignedChatMessage +import de.bixilon.minosoft.data.chat.signature.ChatSignatureProperties +import de.bixilon.minosoft.data.chat.signature.LastSeenMessage +import de.bixilon.minosoft.data.chat.signature.errors.MessageExpiredError +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.EventInitiators +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent 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 import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer +import de.bixilon.minosoft.protocol.protocol.ProtocolVersions import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType +import java.time.Instant @LoadPacket(threadSafe = false) class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val message = buffer.readSignedMessage() - override fun handle(connection: PlayConnection) { - val event = ChatMessageReceiveEvent(connection, this) - if (connection.fireEvent(event)) { - return + + fun PlayInByteBuffer.readLastSeenMessage(): LastSeenMessage { + return LastSeenMessage(readUUID(), readByteArray()) + } + + private fun PlayInByteBuffer.readLegacySignedMessage(): SignedChatMessage { + val message = readChatComponent() + val unsignedContent = if (versionId >= ProtocolVersions.V_22W19A) readOptional { readChatComponent() } else null + var type = readRegistryItem(connection.registries.messageTypeRegistry) + val sender = readChatMessageSender() + val sendingTime = readInstant() + val salt = readLong() + val signatureData = readSignatureData() + + TODO("return message, refactor") + } + + fun PlayInByteBuffer.readSignedMessage(): SignedChatMessage { + if (versionId < ProtocolVersions.V_1_19_1_PRE4) { + return readLegacySignedMessage() } + + val parameters: MutableMap = mutableMapOf() + val header = readMessageHeader() + val signature = readByteArray() + + + val message = readChatComponent().message + if (versionId >= ProtocolVersions.V_1_19_1_PRE5) { + readOptional { readChatComponent() } // formatted text + } + + val sent = readInstant() + val salt = readLong() + val lastSeen = readArray { readLastSeenMessage() } + + parameters[ChatParameter.CONTENT] = TextComponent(message) + val unsigned = readOptional { readChatComponent() } + var filter: Filter? = null + if (versionId >= ProtocolVersions.V_1_19_1_RC3) { + filter = ChatFilter[readVarInt()].reader.invoke(this) + } + val type = readRegistryItem(connection.registries.messageTypeRegistry) + + parameters[ChatParameter.SENDER] = readChatComponent() + readOptional { readChatComponent() }?.let { parameters[ChatParameter.TARGET] = it } + + val sender = connection.getMessageSender(header.sender) + val received = Instant.now() + + var error: Exception? = null + if (received.toEpochMilli() - sent.toEpochMilli() > ChatSignatureProperties.MESSAGE_TTL) { + // expired + error = MessageExpiredError(sent, received) + } else { + // ToDo: check signature + } + + return SignedChatMessage( + connection = connection, + message = message, + type = type, + sender = sender, + parameters = parameters, + filter = filter, + error = error, + sent = sent, + received = received + ) + } + + override fun handle(connection: PlayConnection) { + connection.fireEvent(ChatMessageReceiveEvent(connection, EventInitiators.SERVER, 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 aadee0081..e85d283cd 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 @@ -13,7 +13,10 @@ package de.bixilon.minosoft.protocol.packets.s2c.play.title -import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent +import de.bixilon.minosoft.data.chat.message.SimpleChatMessage +import de.bixilon.minosoft.data.chat.type.DefaultMessageTypes +import de.bixilon.minosoft.modding.event.EventInitiators +import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.packets.factory.LoadPacket import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer @@ -31,6 +34,7 @@ class HotbarTextS2CP(buffer: PlayInByteBuffer) : TitleS2CP { override fun handle(connection: PlayConnection) { Log.log(LogMessageType.CHAT_IN) { "[HOTBAR] $text" } - connection.fireEvent(ChatMessageReceiveEvent(connection, this)) + val message = SimpleChatMessage(text, connection.registries.messageTypeRegistry[DefaultMessageTypes.GAME]!!) + connection.fireEvent(ChatMessageReceiveEvent(connection, EventInitiators.SERVER, message)) } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt b/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt index 3d0e2a7c7..3a9a96750 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt @@ -22,10 +22,7 @@ import de.bixilon.minosoft.commands.nodes.builder.CommandNodeBuilder import de.bixilon.minosoft.commands.parser.factory.ArgumentParserFactories import de.bixilon.minosoft.commands.parser.minosoft.dummy.DummyParser import de.bixilon.minosoft.commands.suggestion.factory.SuggestionFactories -import de.bixilon.minosoft.data.chat.filter.ChatFilter -import de.bixilon.minosoft.data.chat.filter.Filter import de.bixilon.minosoft.data.chat.signature.* -import de.bixilon.minosoft.data.chat.type.MessageType import de.bixilon.minosoft.data.container.ItemStackUtil import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties @@ -364,49 +361,4 @@ class PlayInByteBuffer : InByteBuffer { fun readMessageHeader(): MessageHeader { return MessageHeader(readOptional { readByteArray() }, readUUID()) } - - fun readLastSeenMessage(): LastSeenMessage { - return LastSeenMessage(readUUID(), readByteArray()) - } - - fun readMessageBody(): MessageBody { - val text: ChatComponent = readChatComponent() - if (versionId >= ProtocolVersions.V_1_19_1_PRE5) { - readOptional { readChatComponent() } // decorated content - } - return MessageBody( - text = text, - time = readInstant(), - salt = readLong(), - lastSeen = readArray { readLastSeenMessage() } - ) - } - - fun readMessageType(): MessageType { - return MessageType(readRegistryItem(connection.registries.messageTypeRegistry), readChatComponent(), readOptional { readChatComponent() }) - } - - fun readSignedMessage(): SignedMessage { - if (versionId < ProtocolVersions.V_1_19_1_PRE4) { - val message = readChatComponent() - val unsignedContent = if (versionId >= ProtocolVersions.V_22W19A) readOptional { readChatComponent() } else null - var type = readRegistryItem(connection.registries.messageTypeRegistry) - val sender = readChatMessageSender() - val sendingTime = readInstant() - val salt = readLong() - val signatureData = readSignatureData() - - TODO("return message, refactor") - } - val header = readMessageHeader() - val signature = readByteArray() - val body = readMessageBody() - val unsigned = readOptional { readChatComponent() } - var filter: Filter? = null - if (versionId >= ProtocolVersions.V_1_19_1_RC3) { - filter = ChatFilter[readVarInt()].reader.invoke(this) - } - val type = readMessageType() - return SignedMessage(header, signature, body, unsigned, type, filter) - } }