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)
- }
}