From 1537eeee95db81ff752dc2c805a98a41709e39ed Mon Sep 17 00:00:00 2001 From: Bixilon Date: Tue, 25 Oct 2022 18:22:28 +0200 Subject: [PATCH] network: 22w42a unsigned chat message --- .../data/chat/message/FormattedChatMessage.kt | 41 +++++++++++++++++ .../data/chat/message/SignedChatMessage.kt | 22 ++------- .../s2c/play/chat/SignedChatMessageS2CP.kt | 3 +- .../s2c/play/chat/UnsignedChatMessageS2CP.kt | 45 +++++++++++++++++++ .../protocol/protocol/PlayInByteBuffer.kt | 6 +++ .../assets/minosoft/mapping/versions.json | 2 +- 6 files changed, 97 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/data/chat/message/FormattedChatMessage.kt create mode 100644 src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt diff --git a/src/main/java/de/bixilon/minosoft/data/chat/message/FormattedChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/FormattedChatMessage.kt new file mode 100644 index 000000000..eeeebc68e --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/FormattedChatMessage.kt @@ -0,0 +1,41 @@ +/* + * 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.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 + +open class FormattedChatMessage( + private val connection: PlayConnection, + final override val type: ChatMessageType, + val parameters: Map, +) : ChatMessage { + final 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/SignedChatMessage.kt b/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt index 220d0cda4..c53e18e14 100644 --- a/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt +++ b/src/main/java/de/bixilon/minosoft/data/chat/message/SignedChatMessage.kt @@ -13,38 +13,22 @@ 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, + type: ChatMessageType, override val sender: MessageSender, - val parameters: Map, + 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) - } -} +) : FormattedChatMessage(connection, type, parameters), ChatMessage, PlayerSentMessage 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 a57b4aeca..267b4f554 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 @@ -82,8 +82,7 @@ class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { } val type = readRegistryItem(connection.registries.messageTypeRegistry) - parameters[ChatParameter.SENDER] = readChatComponent() - readOptional { readChatComponent() }?.let { parameters[ChatParameter.TARGET] = it } + readChatMessageParameters(parameters) val sender = connection.getMessageSender(header.sender) val received = Instant.now() diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt new file mode 100644 index 000000000..216f063b6 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/chat/UnsignedChatMessageS2CP.kt @@ -0,0 +1,45 @@ +/* + * 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.protocol.packets.s2c.play.chat + +import de.bixilon.minosoft.data.chat.message.FormattedChatMessage +import de.bixilon.minosoft.data.registries.chat.ChatParameter +import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.modding.event.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.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType + +@LoadPacket(threadSafe = false) +class UnsignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { + val text: ChatComponent = buffer.readChatComponent() + val type = buffer.readRegistryItem(buffer.connection.registries.messageTypeRegistry) + val parameters: Map = mutableMapOf().apply { + buffer.readChatMessageParameters(this) + this[ChatParameter.CONTENT] = text + } + + override fun handle(connection: PlayConnection) { + val message = FormattedChatMessage(connection, type, parameters) + connection.fireEvent(ChatMessageReceiveEvent(connection, EventInitiators.SERVER, message)) + } + + override fun log(reducedLog: Boolean) { + Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Chat message (text=$text, parameters=$parameters)" } + } +} 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 2f50ab941..298f6eaec 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt @@ -28,6 +28,7 @@ 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.textures.PlayerTextures import de.bixilon.minosoft.data.registries.biomes.Biome +import de.bixilon.minosoft.data.registries.chat.ChatParameter import de.bixilon.minosoft.data.registries.particle.ParticleType import de.bixilon.minosoft.data.registries.particle.data.BlockParticleData import de.bixilon.minosoft.data.registries.particle.data.DustParticleData @@ -383,4 +384,9 @@ class PlayInByteBuffer : InByteBuffer { } return set } + + fun readChatMessageParameters(parameters: MutableMap) { + parameters[ChatParameter.SENDER] = readChatComponent() + readOptional { readChatComponent() }?.let { parameters[ChatParameter.TARGET] = it } + } } diff --git a/src/main/resources/assets/minosoft/mapping/versions.json b/src/main/resources/assets/minosoft/mapping/versions.json index 23401b544..84bf3cca4 100644 --- a/src/main/resources/assets/minosoft/mapping/versions.json +++ b/src/main/resources/assets/minosoft/mapping/versions.json @@ -4,7 +4,7 @@ "protocol_id": 1073741928, "packets": { "c2s": ["confirm_teleport", "block_nbt", "difficulty", "message_acknowledgement", "command", "signed_chat_message", "client_action", "settings", "command_suggestions", "container_button", "container_click", "close_container", "plugin", "book", "entity_nbt", "entity_interact", "generate_structure", "heartbeat", "lock_difficulty", "position", "position_rotation", "rotation", "ground_change", "move_vehicle", "steer_boat", "item_pick", "crafting_recipe", "toggle_fly", "player_action", "entity_action", "steer_vehicle", "pong", "displayed_recipe", "recipe_book", "anvil_item_name", "resourcepack", "advancement_tab", "trade", "beacon_effect", "hotbar_slot", "command_block", "minecart_command_block", "item_stack_create", "jigsaw_block", "structure_block", "sign_text", "swing_arm", "entity_spectate", "block_interact", "use_item"], - "s2c": ["entity_object_spawn", "entity_experience_orb", "entity_player", "entity_animation", "statistics", "block_break", "block_break_animation", "block_data", "block_action", "block", "bossbar", "difficulty", "clear_title", "command_suggestions", "commands", "close_container", "container_items", "container_properties", "container_item", "item_cooldown", "chat_suggestions", "plugin", "named_sound", "hide_message", "kick", "profileless_chat_message", "entity_status", "explosion", "unload_chunk", "game_event", "open_horse_container", "initialize_world_border", "heartbeat", "chunk", "world_event", "particle", "chunk_light", "initialize", "map", "villager_trades", "relative_move", "movement_rotation", "rotation", "move_vehicle", "book", "open_container", "sign_editor", "ping", "crafting_recipe", "player_abilities", "signed_chat_message", "end_combat_event", "enter_combat_event", "kill_combat_event", "player_remove", "tab_list", "player_face", "position_rotation", "unlock_recipes", "entity_destroy", "entity_remove_effect", "resourcepack", "respawn", "head_rotation", "blocks", "advancement_tab", "play_status", "hotbar_text", "center_world_border", "interpolate_world_border", "size_world_border", "warn_time_world_border", "warn_blocks_world_border", "camera", "hotbar_slot", "chunk_center", "view_distance", "compass_position", "objective_position", "entity_data", "entity_attach", "velocity", "entity_equipment", "experience", "health", "objective", "entity_passenger", "teams", "scoreboard_score", "simulation_distance", "subtitle", "time", "title_text", "title_times", "entity_sound", "sound_event", "stop_sound", "chat_message", "tab_list_text", "nbt_response", "entity_collect", "teleport", "advancements", "entity_attributes", "features", "entity_effect", "recipes", "tags"] + "s2c": ["entity_object_spawn", "entity_experience_orb", "entity_player", "entity_animation", "statistics", "block_break", "block_break_animation", "block_data", "block_action", "block", "bossbar", "difficulty", "clear_title", "command_suggestions", "commands", "close_container", "container_items", "container_properties", "container_item", "item_cooldown", "chat_suggestions", "plugin", "named_sound", "hide_message", "kick", "unsigned_chat_message", "entity_status", "explosion", "unload_chunk", "game_event", "open_horse_container", "initialize_world_border", "heartbeat", "chunk", "world_event", "particle", "chunk_light", "initialize", "map", "villager_trades", "relative_move", "movement_rotation", "rotation", "move_vehicle", "book", "open_container", "sign_editor", "ping", "crafting_recipe", "player_abilities", "signed_chat_message", "end_combat_event", "enter_combat_event", "kill_combat_event", "player_remove", "tab_list", "player_face", "position_rotation", "unlock_recipes", "entity_destroy", "entity_remove_effect", "resourcepack", "respawn", "head_rotation", "blocks", "advancement_tab", "play_status", "hotbar_text", "center_world_border", "interpolate_world_border", "size_world_border", "warn_time_world_border", "warn_blocks_world_border", "camera", "hotbar_slot", "chunk_center", "view_distance", "compass_position", "objective_position", "entity_data", "entity_attach", "velocity", "entity_equipment", "experience", "health", "objective", "entity_passenger", "teams", "scoreboard_score", "simulation_distance", "subtitle", "time", "title_text", "title_times", "entity_sound", "sound_event", "stop_sound", "chat_message", "tab_list_text", "nbt_response", "entity_collect", "teleport", "advancements", "entity_attributes", "features", "entity_effect", "recipes", "tags"] } }, "862": {