mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 11:54:59 -04:00
wip: refactor chatting, signed chat: chat formatting
This commit is contained in:
parent
e99f47b845
commit
f4bb0f2c52
36
src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt
Normal file
36
src/main/java/de/bixilon/minosoft/data/chat/ChatUtil.kt
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
@ -13,8 +13,10 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.chat.message
|
package de.bixilon.minosoft.data.chat.message
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.registries.chat.ChatMessageType
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
|
||||||
interface ChatMessage {
|
interface ChatMessage {
|
||||||
val text: ChatComponent
|
val text: ChatComponent
|
||||||
|
val type: ChatMessageType
|
||||||
}
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.chat.message
|
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 de.bixilon.minosoft.data.text.ChatComponent
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
open class PlayerChatMessage(
|
open class PlayerChatMessage(
|
||||||
text: ChatComponent,
|
text: ChatComponent,
|
||||||
type: DefaultMessageTypes,
|
type: ChatMessageType,
|
||||||
val sender: UUID,
|
override val sender: MessageSender,
|
||||||
) : SimpleChatMessage(text, type)
|
) : SimpleChatMessage(text, type), PlayerSentMessage
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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<ChatParameter, ChatComponent>,
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
@ -13,10 +13,15 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.chat.message
|
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
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
|
||||||
open class SimpleChatMessage(
|
open class SimpleChatMessage(
|
||||||
override val text: ChatComponent,
|
override val text: ChatComponent,
|
||||||
val type: DefaultMessageTypes,
|
override val type: ChatMessageType,
|
||||||
) : ChatMessage
|
) : ChatMessage {
|
||||||
|
init {
|
||||||
|
text.setFallbackColor(ChatUtil.DEFAULT_CHAT_COLOR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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)
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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)
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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")
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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")
|
@ -25,52 +25,12 @@ class Language(
|
|||||||
) : Translator {
|
) : Translator {
|
||||||
|
|
||||||
override fun canTranslate(key: ResourceLocation?): Boolean {
|
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 {
|
override fun translate(key: ResourceLocation?, parent: TextComponent?, vararg data: Any?): ChatComponent {
|
||||||
val placeholder = this.data[key?.path] ?: return LanguageUtil.getFallbackTranslation(key, parent, data)
|
val placeholder = this.data[key?.path] ?: return LanguageUtil.getFallbackTranslation(key, parent, data)
|
||||||
|
return Companion.translate(placeholder, parent, this, *data)
|
||||||
val ret = BaseComponent()
|
|
||||||
|
|
||||||
val arguments: MutableList<Any?> = mutableListOf()
|
|
||||||
var splitPlaceholder: List<String> = 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -80,5 +40,50 @@ class Language(
|
|||||||
companion object {
|
companion object {
|
||||||
private val FORMATTER_ORDER_REGEX = "%(\\w+)\\\$[sd]".toRegex() // %1$s fell from a high place
|
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
|
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<Any?> = mutableListOf()
|
||||||
|
var splitPlaceholder: List<String> = 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,10 @@ class ChatMessageType(
|
|||||||
val position: ChatTextPositions,
|
val position: ChatTextPositions,
|
||||||
) : RegistryItem() {
|
) : RegistryItem() {
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return resourceLocation.toString()
|
||||||
|
}
|
||||||
|
|
||||||
companion object : ResourceLocationCodec<ChatMessageType> {
|
companion object : ResourceLocationCodec<ChatMessageType> {
|
||||||
|
|
||||||
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): ChatMessageType {
|
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): ChatMessageType {
|
||||||
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.registries.chat
|
|||||||
import de.bixilon.kutil.json.JsonObject
|
import de.bixilon.kutil.json.JsonObject
|
||||||
import de.bixilon.kutil.json.JsonUtil.asJsonList
|
import de.bixilon.kutil.json.JsonUtil.asJsonList
|
||||||
import de.bixilon.kutil.json.JsonUtil.asJsonObject
|
import de.bixilon.kutil.json.JsonUtil.asJsonObject
|
||||||
|
import de.bixilon.minosoft.data.text.ChatComponent
|
||||||
|
|
||||||
class TypeProperties(
|
class TypeProperties(
|
||||||
val translationKey: String,
|
val translationKey: String,
|
||||||
@ -23,6 +24,16 @@ class TypeProperties(
|
|||||||
val style: Map<String, Any>,
|
val style: Map<String, Any>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
fun formatParameters(parameters: Map<ChatParameter, ChatComponent>): Array<ChatComponent> {
|
||||||
|
val output: MutableList<ChatComponent> = mutableListOf()
|
||||||
|
|
||||||
|
for (parameter in this.parameters) {
|
||||||
|
output += parameters[parameter] ?: continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun deserialize(data: JsonObject): TypeProperties {
|
fun deserialize(data: JsonObject): TypeProperties {
|
||||||
|
@ -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.GUIVertexConsumer
|
||||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
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.InternalMessageReceiveEvent
|
||||||
|
import de.bixilon.minosoft.modding.event.events.chat.ChatMessageReceiveEvent
|
||||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
|
||||||
@ -82,16 +82,16 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer),
|
|||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||||
if (it.type.position == ChatTextPositions.HOTBAR) {
|
if (it.message.type.position == ChatTextPositions.HOTBAR) {
|
||||||
return@of
|
return@of
|
||||||
}
|
}
|
||||||
DefaultThreadPool += { messages += it.message }
|
DefaultThreadPool += { messages += it.message.text }
|
||||||
})
|
})
|
||||||
connection.registerEvent(CallbackEventInvoker.of<InternalMessageReceiveEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<InternalMessageReceiveEvent> {
|
||||||
if (!profile.chat.internal.hidden) {
|
if (!profile.chat.internal.hidden) {
|
||||||
return@of
|
return@of
|
||||||
}
|
}
|
||||||
DefaultThreadPool += { messages += it.message }
|
DefaultThreadPool += { messages += it.message.text }
|
||||||
})
|
})
|
||||||
|
|
||||||
renderWindow.inputHandler.registerKeyCallback(
|
renderWindow.inputHandler.registerKeyCallback(
|
||||||
|
@ -51,7 +51,7 @@ class InternalChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRen
|
|||||||
if (profile.chat.internal.hidden) {
|
if (profile.chat.internal.hidden) {
|
||||||
return@of
|
return@of
|
||||||
}
|
}
|
||||||
DefaultThreadPool += { messages += it.message }
|
DefaultThreadPool += { messages += it.message.text }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.vec2.Vec2iUtil.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec4.Vec4iUtil.left
|
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.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.ExperienceChangeEvent
|
||||||
import de.bixilon.minosoft.modding.event.events.SelectHotbarSlotEvent
|
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.modding.event.invoker.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
import java.lang.Integer.max
|
import java.lang.Integer.max
|
||||||
@ -179,7 +179,7 @@ class HotbarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedEl
|
|||||||
connection.registerEvent(CallbackEventInvoker.of<SelectHotbarSlotEvent> { core.base.apply() })
|
connection.registerEvent(CallbackEventInvoker.of<SelectHotbarSlotEvent> { core.base.apply() })
|
||||||
|
|
||||||
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||||
if (it.type.position != ChatTextPositions.HOTBAR) {
|
if (it.message.type.position != ChatTextPositions.HOTBAR) {
|
||||||
return@of
|
return@of
|
||||||
}
|
}
|
||||||
hoverText.text = it.message
|
hoverText.text = it.message
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* 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)
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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
|
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.EventInitiators
|
||||||
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
||||||
class InternalMessageReceiveEvent(
|
class InternalMessageReceiveEvent(
|
||||||
connection: PlayConnection,
|
connection: PlayConnection,
|
||||||
val message: ChatComponent,
|
val message: InternalChatMessage,
|
||||||
) : PlayConnectionEvent(connection, EventInitiators.CLIENT), CancelableEvent
|
) : PlayConnectionEvent(connection, EventInitiators.CLIENT), CancelableEvent
|
||||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* 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
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Minosoft
|
* 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.
|
* 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.
|
* 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.EventInitiators
|
||||||
|
import de.bixilon.minosoft.modding.event.events.CancelableEvent
|
||||||
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
|
||||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.protocol.network.connection.play
|
|||||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||||
import de.bixilon.kutil.string.WhitespaceUtil.trimWhitespaces
|
import de.bixilon.kutil.string.WhitespaceUtil.trimWhitespaces
|
||||||
import de.bixilon.minosoft.commands.stack.CommandStack
|
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.Acknowledgement
|
||||||
import de.bixilon.minosoft.data.chat.signature.MessageChain
|
import de.bixilon.minosoft.data.chat.signature.MessageChain
|
||||||
import de.bixilon.minosoft.data.text.BaseComponent
|
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.data.text.formatting.color.ChatColors
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
|
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.InternalMessageReceiveEvent
|
||||||
|
import de.bixilon.minosoft.modding.event.events.chat.ChatMessageSendEvent
|
||||||
import de.bixilon.minosoft.modding.event.events.container.ContainerCloseEvent
|
import de.bixilon.minosoft.modding.event.events.container.ContainerCloseEvent
|
||||||
import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork
|
import de.bixilon.minosoft.protocol.ProtocolUtil.encodeNetwork
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.chat.ChatMessageC2SP
|
import de.bixilon.minosoft.protocol.packets.c2s.play.chat.ChatMessageC2SP
|
||||||
@ -46,14 +47,14 @@ class ConnectionUtil(
|
|||||||
|
|
||||||
fun sendDebugMessage(message: Any) {
|
fun sendDebugMessage(message: Any) {
|
||||||
val component = BaseComponent(RenderConstants.DEBUG_MESSAGES_PREFIX, ChatComponent.of(message).apply { this.setFallbackColor(ChatColors.BLUE) })
|
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 }
|
Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { component }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendInternal(message: Any) {
|
fun sendInternal(message: Any) {
|
||||||
val component = ChatComponent.of(message)
|
val component = ChatComponent.of(message)
|
||||||
val prefixed = BaseComponent(RenderConstants.INTERNAL_MESSAGES_PREFIX, component)
|
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 }
|
Log.log(LogMessageType.CHAT_IN, LogLevels.INFO) { prefixed }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ import de.bixilon.minosoft.data.text.ChatComponent
|
|||||||
import de.bixilon.minosoft.data.world.World
|
import de.bixilon.minosoft.data.world.World
|
||||||
import de.bixilon.minosoft.gui.eros.dialog.ErosErrorReport.Companion.report
|
import de.bixilon.minosoft.gui.eros.dialog.ErosErrorReport.Companion.report
|
||||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
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.events.loading.RegistriesLoadEvent
|
||||||
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker
|
||||||
import de.bixilon.minosoft.protocol.network.connection.Connection
|
import de.bixilon.minosoft.protocol.network.connection.Connection
|
||||||
@ -151,12 +151,12 @@ class PlayConnection(
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||||
val additionalPrefix = when (it.type.position) {
|
val additionalPrefix = when (it.message.type.position) {
|
||||||
ChatTextPositions.SYSTEM -> "[SYSTEM] "
|
ChatTextPositions.SYSTEM -> "[SYSTEM] "
|
||||||
ChatTextPositions.HOTBAR -> "[HOTBAR] "
|
ChatTextPositions.HOTBAR -> "[HOTBAR] "
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
Log.log(LogMessageType.CHAT_IN, additionalPrefix = ChatComponent.of(additionalPrefix)) { it.message }
|
Log.log(LogMessageType.CHAT_IN, additionalPrefix = ChatComponent.of(additionalPrefix)) { it.message.text }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,15 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.protocol.packets.s2c.play.chat
|
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.chat.type.DefaultMessageTypes
|
||||||
import de.bixilon.minosoft.data.registries.chat.ChatMessageType
|
import de.bixilon.minosoft.data.registries.chat.ChatMessageType
|
||||||
import de.bixilon.minosoft.data.text.ChatComponent
|
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.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||||
@ -29,7 +34,7 @@ import java.util.*
|
|||||||
|
|
||||||
@LoadPacket(threadSafe = false)
|
@LoadPacket(threadSafe = false)
|
||||||
class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
||||||
val message: ChatComponent = buffer.readChatComponent()
|
val text: ChatComponent = buffer.readChatComponent()
|
||||||
var type: ChatMessageType = buffer.connection.registries.messageTypeRegistry[DefaultMessageTypes.CHAT]!!
|
var type: ChatMessageType = buffer.connection.registries.messageTypeRegistry[DefaultMessageTypes.CHAT]!!
|
||||||
private set
|
private set
|
||||||
var sender: UUID? = null
|
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) {
|
override fun handle(connection: PlayConnection) {
|
||||||
val event = ChatMessageReceiveEvent(connection, this)
|
val type = if (overlay) connection.registries.messageTypeRegistry[DefaultMessageTypes.GAME]!! else type
|
||||||
if (connection.fireEvent(event)) {
|
val sender = sender
|
||||||
return
|
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) {
|
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)" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,105 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.protocol.packets.s2c.play.chat
|
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.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
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.Log
|
||||||
import de.bixilon.minosoft.util.logging.LogLevels
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
@LoadPacket(threadSafe = false)
|
@LoadPacket(threadSafe = false)
|
||||||
class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
|
||||||
val message = buffer.readSignedMessage()
|
val message = buffer.readSignedMessage()
|
||||||
|
|
||||||
override fun handle(connection: PlayConnection) {
|
|
||||||
val event = ChatMessageReceiveEvent(connection, this)
|
fun PlayInByteBuffer.readLastSeenMessage(): LastSeenMessage {
|
||||||
if (connection.fireEvent(event)) {
|
return LastSeenMessage(readUUID(), readByteArray())
|
||||||
return
|
}
|
||||||
|
|
||||||
|
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<ChatParameter, ChatComponent> = 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) {
|
override fun log(reducedLog: Boolean) {
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.protocol.packets.s2c.play.title
|
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.network.connection.play.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
|
||||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
||||||
@ -31,6 +34,7 @@ class HotbarTextS2CP(buffer: PlayInByteBuffer) : TitleS2CP {
|
|||||||
|
|
||||||
override fun handle(connection: PlayConnection) {
|
override fun handle(connection: PlayConnection) {
|
||||||
Log.log(LogMessageType.CHAT_IN) { "[HOTBAR] $text" }
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.factory.ArgumentParserFactories
|
||||||
import de.bixilon.minosoft.commands.parser.minosoft.dummy.DummyParser
|
import de.bixilon.minosoft.commands.parser.minosoft.dummy.DummyParser
|
||||||
import de.bixilon.minosoft.commands.suggestion.factory.SuggestionFactories
|
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.signature.*
|
||||||
import de.bixilon.minosoft.data.chat.type.MessageType
|
|
||||||
import de.bixilon.minosoft.data.container.ItemStackUtil
|
import de.bixilon.minosoft.data.container.ItemStackUtil
|
||||||
import de.bixilon.minosoft.data.container.stack.ItemStack
|
import de.bixilon.minosoft.data.container.stack.ItemStack
|
||||||
import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties
|
import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties
|
||||||
@ -364,49 +361,4 @@ class PlayInByteBuffer : InByteBuffer {
|
|||||||
fun readMessageHeader(): MessageHeader {
|
fun readMessageHeader(): MessageHeader {
|
||||||
return MessageHeader(readOptional { readByteArray() }, readUUID())
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user