network: 22w18a

This commit is contained in:
Bixilon 2022-05-15 20:29:15 +02:00
parent 8f4239f069
commit 5bdfa454f6
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
20 changed files with 151 additions and 35 deletions

View File

@ -0,0 +1,35 @@
/*
* 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.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
enum class ChatMessageTypes(val position: ChatTextPositions = ChatTextPositions.CHAT) {
CHAT_MESSAGE,
SYSTEM_MESSAGE,
GAME_MESSAGE,
COMMAND_SAY,
COMMAND_MSG,
COMMAND_TEAM_MSG,
COMMAND_EMOTE,
COMMAND_TELLRAW,
;
companion object : ValuesEnum<ChatMessageTypes> {
override val VALUES: Array<ChatMessageTypes> = values()
override val NAME_MAP: Map<String, ChatMessageTypes> = EnumUtil.getEnumValues(VALUES)
}
}

View File

@ -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,15 +10,15 @@
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data
package de.bixilon.minosoft.data.chat
import de.bixilon.kutil.enums.EnumUtil
import de.bixilon.kutil.enums.ValuesEnum
enum class ChatTextPositions {
CHAT_BOX,
SYSTEM_MESSAGE,
ABOVE_HOTBAR,
CHAT,
SYSTEM,
HOTBAR,
;
companion object : ValuesEnum<ChatTextPositions> {

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2021 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.
*
@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.player.properties.PlayerProperties
import de.bixilon.minosoft.data.scoreboard.Team
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.PlayerPublicKey
import de.bixilon.minosoft.util.KUtil.nullCompare
data class TabListItem(
@ -26,16 +27,18 @@ data class TabListItem(
var displayName: ChatComponent = ChatComponent.of(name),
var properties: PlayerProperties = PlayerProperties(),
var team: Team? = null,
var publicKey: PlayerPublicKey? = null,
) : Comparable<TabListItem> {
val tabDisplayName: ChatComponent
get() = team?.decorateName(displayName) ?: displayName
fun merge(data: TabListItemData) {
specialMerge(data)
genericMerge(data)
data.gamemode?.let { gamemode = it }
data.publicKey?.let { publicKey = it }
}
fun specialMerge(data: TabListItemData) {
fun genericMerge(data: TabListItemData) {
data.name?.let { name = it }
data.ping?.let { ping = it }

View File

@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.player.properties.PlayerProperties
import de.bixilon.minosoft.data.scoreboard.Team
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.PlayerPublicKey
data class TabListItemData(
val name: String? = null,
@ -27,4 +28,5 @@ data class TabListItemData(
val properties: PlayerProperties? = null,
var team: Team? = null,
var removeFromTeam: Boolean = false,
var publicKey: PlayerPublicKey? = null,
)

View File

@ -19,7 +19,7 @@ import de.bixilon.minosoft.config.key.KeyActions
import de.bixilon.minosoft.config.key.KeyBinding
import de.bixilon.minosoft.config.key.KeyCodes
import de.bixilon.minosoft.config.profile.delegate.watcher.SimpleProfileDelegateWatcher.Companion.profileWatchRendering
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.chat.ChatTextPositions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.font.Font
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
@ -80,7 +80,7 @@ class ChatElement(guiRenderer: GUIRenderer) : AbstractChatElement(guiRenderer),
override fun init() {
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
if (it.position == ChatTextPositions.ABOVE_HOTBAR) {
if (it.type.position == ChatTextPositions.HOTBAR) {
return@of
}
DefaultThreadPool += { messages += it.message }

View File

@ -14,8 +14,8 @@
package de.bixilon.minosoft.gui.rendering.gui.hud.elements.hotbar
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.chat.ChatTextPositions
import de.bixilon.minosoft.data.container.InventorySlots
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.player.Arms
@ -179,7 +179,7 @@ class HotbarElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedEl
connection.registerEvent(CallbackEventInvoker.of<SelectHotbarSlotEvent> { core.base.apply() })
connection.registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
if (it.position != ChatTextPositions.ABOVE_HOTBAR) {
if (it.type.position != ChatTextPositions.HOTBAR) {
return@of
}
hoverText.text = it.message

View File

@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.modding.event.events
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.chat.ChatMessageTypes
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.modding.event.EventInitiators
import de.bixilon.minosoft.modding.event.events.connection.play.PlayConnectionEvent
@ -26,14 +26,14 @@ class ChatMessageReceiveEvent(
connection: PlayConnection,
initiator: EventInitiators,
val message: ChatComponent,
val position: ChatTextPositions,
val type: ChatMessageTypes,
val sender: UUID?,
) : PlayConnectionEvent(connection, initiator), CancelableEvent {
constructor(connection: PlayConnection, packet: ChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message, packet.position, packet.sender)
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, ChatTextPositions.ABOVE_HOTBAR, null)
constructor(connection: PlayConnection, packet: HotbarTextS2CP) : this(connection, EventInitiators.SERVER, packet.text, ChatMessageTypes.GAME_MESSAGE, null)
constructor(connection: PlayConnection, packet: SignedChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message, packet.position, packet.sender.uuid)
constructor(connection: PlayConnection, packet: SignedChatMessageS2CP) : this(connection, EventInitiators.SERVER, packet.message, packet.type, packet.sender.uuid)
}

View File

@ -14,13 +14,16 @@
package de.bixilon.minosoft.protocol
import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.primitive.LongUtil.toLong
class PlayerPublicKey(
val expiresAt: Long,
val keyString: String,
val signate: String,
val signature: String,
) {
constructor(nbt: JsonObject) : this(nbt["expires_at"].toLong(), nbt["key"].toString(), nbt["signature"].toString())
fun toNbt(): JsonObject {
TODO()
}

View File

@ -21,9 +21,9 @@ import de.bixilon.kutil.watcher.DataWatcher.Companion.watched
import de.bixilon.minosoft.assets.AssetsLoader
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.config.profile.ConnectionProfiles
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.accounts.Account
import de.bixilon.minosoft.data.bossbar.BossbarManager
import de.bixilon.minosoft.data.chat.ChatTextPositions
import de.bixilon.minosoft.data.commands.CommandRootNode
import de.bixilon.minosoft.data.language.LanguageManager
import de.bixilon.minosoft.data.physics.CollisionDetector
@ -152,9 +152,9 @@ class PlayConnection(
}
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
val additionalPrefix = when (it.position) {
ChatTextPositions.SYSTEM_MESSAGE -> "[SYSTEM] "
ChatTextPositions.ABOVE_HOTBAR -> "[HOTBAR] "
val additionalPrefix = when (it.type.position) {
ChatTextPositions.SYSTEM -> "[SYSTEM] "
ChatTextPositions.HOTBAR -> "[HOTBAR] "
else -> ""
}
Log.log(LogMessageType.CHAT_IN, additionalPrefix = ChatComponent.of(additionalPrefix)) { it.message }

View File

@ -75,7 +75,7 @@ class PacketDecoder(
}
val packet = type.factory?.createPacket(buffer) ?: throw IllegalStateException("Packet factory is null?")
if (buffer.pointer < buffer.size) {
throw PacketBufferUnderflowException(type, buffer.size, buffer.pointer)
throw PacketBufferUnderflowException(type, buffer.size, buffer.size - buffer.pointer)
}
return packet.unsafeCast()
}

View File

@ -30,16 +30,19 @@ class ChatMessageC2SP(
) : PlayC2SPacket {
override fun write(buffer: PlayOutByteBuffer) {
if (buffer.versionId >= ProtocolVersions.V_22W17A) {
if (buffer.versionId == ProtocolVersions.V_22W17A) {
buffer.writeLong(time)
}
buffer.writeString(message)
if (buffer.versionId >= ProtocolVersions.V_22W18A) {
buffer.writeLong(time)
}
if (buffer.versionId >= ProtocolVersions.V_22W17A) {
buffer.writeSignatureData(signature ?: SignatureData.EMPTY)
}
}
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_PACKETS_OUT, LogLevels.VERBOSE) { "Chat message (time=${time}, message=$message, signature=$signature)" }
Log.log(LogMessageType.NETWORK_PACKETS_OUT, LogLevels.VERBOSE) { "Chat message (message=$message, time=$time, signature=$signature)" }
}
}

View File

@ -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.protocol.packets.c2s.play.chat
import de.bixilon.kutil.time.TimeUtil
import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
import de.bixilon.minosoft.protocol.protocol.PlayOutByteBuffer
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 CommandC2SP(
val command: String,
val time: Long = TimeUtil.seconds,
val signature: CommandArgumentSignature,
) : PlayC2SPacket {
override fun write(buffer: PlayOutByteBuffer) {
buffer.writeString(command)
buffer.writeLong(time)
buffer.writeLong(signature.salt)
buffer.writeVarInt(signature.signatures.size)
for ((argument, signature) in signature.signatures) {
buffer.writeString(argument)
buffer.writeByteArray(signature)
}
}
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_PACKETS_OUT, LogLevels.VERBOSE) { "Chat message (message=$command, time=$time, signature=$signature)" }
}
data class CommandArgumentSignature(
val salt: Long,
val signatures: Map<String, ByteArray>,
)
}

View File

@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.protocol.packets.s2c.play.chat
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.chat.ChatMessageTypes
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -29,14 +29,14 @@ import java.util.*
@LoadPacket(threadSafe = false)
class ChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val message: ChatComponent = buffer.readChatComponent()
var position: ChatTextPositions = ChatTextPositions.CHAT_BOX
var type: ChatMessageTypes = ChatMessageTypes.CHAT_MESSAGE
private set
var sender: UUID? = null
private set
init {
if (buffer.versionId >= ProtocolVersions.V_14W04A) {
position = ChatTextPositions[buffer.readUnsignedByte()]
type = ChatMessageTypes[buffer.readVarInt()]
if (buffer.versionId >= ProtocolVersions.V_20W21A && buffer.versionId < ProtocolVersions.V_22W17A) {
sender = buffer.readUUID()
}

View File

@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.protocol.packets.s2c.play.chat
import de.bixilon.minosoft.data.ChatTextPositions
import de.bixilon.minosoft.data.chat.ChatMessageTypes
import de.bixilon.minosoft.modding.event.events.ChatMessageReceiveEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.factory.LoadPacket
@ -25,7 +25,7 @@ import de.bixilon.minosoft.util.logging.LogMessageType
@LoadPacket(threadSafe = false)
class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val message = buffer.readChatComponent()
var position = ChatTextPositions[buffer.readUnsignedByte()]
var type = ChatMessageTypes[buffer.readVarInt()]
val sender = buffer.readChatMessageSender()
val sendingTime = buffer.readLong()
val signatureData = buffer.readSignatureData()
@ -38,6 +38,6 @@ class SignedChatMessageS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
}
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Chat message (message=\"$message\", position=$position, sender=$sender, sendingTime=$sendingTime, signateDate=$signatureData)" }
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Chat message (message=\"$message\", type=$type, sender=$sender, sendingTime=$sendingTime, signateDate=$signatureData)" }
}
}

View File

@ -24,6 +24,7 @@ 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
@ -51,13 +52,14 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
} else {
null
}
val publicKey = if (buffer.versionId >= ProtocolVersions.V_22W18A) buffer.readPlayerPublicKey() else null
data = TabListItemData(
name = name,
properties = properties,
gamemode = gamemode,
ping = ping,
hasDisplayName = hasDisplayName,
displayName = displayName,
publicKey = publicKey,
)
}
TabListItemActions.UPDATE_GAMEMODE -> {
@ -122,7 +124,7 @@ class TabListS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
} ?: continue
if (entity === connection.player) {
entity.tabListItem.specialMerge(data)
entity.tabListItem.genericMerge(data)
} else {
tabListItem.merge(data)
if (entity == null || entity !is PlayerEntity) {

View File

@ -19,4 +19,5 @@ import java.util.*
class ChatMessageSender(
val uuid: UUID,
val name: ChatComponent,
val team: ChatComponent?,
)

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.protocol
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.json.JsonUtil.asJsonObject
import de.bixilon.kutil.json.JsonUtil.toMutableJsonObject
import de.bixilon.minosoft.data.container.ItemStackUtil
import de.bixilon.minosoft.data.container.stack.ItemStack
@ -25,6 +26,7 @@ import de.bixilon.minosoft.data.registries.particle.data.DustParticleData
import de.bixilon.minosoft.data.registries.particle.data.ItemParticleData
import de.bixilon.minosoft.data.registries.particle.data.ParticleData
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.PlayerPublicKey
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W04A
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_14W21A
@ -257,10 +259,14 @@ class PlayInByteBuffer : InByteBuffer {
}
fun readChatMessageSender(): ChatMessageSender {
return ChatMessageSender(readUUID(), readChatComponent())
return ChatMessageSender(readUUID(), readChatComponent(), if (versionId >= ProtocolVersions.V_22W18A) readOptional { readChatComponent() } else null)
}
fun readSignatureData(): SignatureData {
return SignatureData(readLong(), readByteArray())
}
fun readPlayerPublicKey(): PlayerPublicKey? {
return readNBT()?.let { PlayerPublicKey(it.asJsonObject()) }
}
}

View File

@ -14,6 +14,7 @@ package de.bixilon.minosoft.protocol.protocol
@Suppress("UNUSED")
object ProtocolVersions {
const val V_22W18A = 839
const val V_22W17A = 838
const val V_22W16B = 837
const val V_22W16A = 836

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,14 @@
{
"839": {
"name": "22w18a",
"protocol_id": 1073741907,
"packets": {
"c2s": ["confirm_teleport", "block_nbt", "difficulty", "command", "chat_message", "client_action", "settings", "chat_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", "chat_suggestions", "commands", "close_container", "container_items", "container_properties", "container_item", "item_cooldown", "plugin", "named_sound", "kick", "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", "tab_list", "player_face", "position_rotation", "unlock_recipes", "entity_destroy", "entity_remove_effect", "resourcepack", "respawn", "head_rotation", "blocks", "advancement_tab", "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", "entity_effect", "recipes", "tags"
]
}
},
"838": {
"name": "22w17a",
"protocol_id": 1073741906,