From 3bc879fcca129b9aa731972340085b77d20a0d03 Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Wed, 26 Jul 2023 23:00:32 +0200 Subject: [PATCH] network: CommandsS2CP test --- .../packets/s2c/play/CommandsS2CPTest.kt | 50 ++++++++++++++++++ .../packets/s2c/play/PacketReadingTestUtil.kt | 30 +++++++++++ .../packets/commands/vanilla_op_1_15_2.bin | Bin 0 -> 24981 bytes .../packets/commands/vanilla_op_1_19_3.bin | Bin 0 -> 16909 bytes .../packets/commands/vanilla_op_1_20_1.bin | Bin 0 -> 20260 bytes 5 files changed, 80 insertions(+) create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/CommandsS2CPTest.kt create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/PacketReadingTestUtil.kt create mode 100644 src/integration-test/resources/packets/commands/vanilla_op_1_15_2.bin create mode 100644 src/integration-test/resources/packets/commands/vanilla_op_1_19_3.bin create mode 100644 src/integration-test/resources/packets/commands/vanilla_op_1_20_1.bin diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/CommandsS2CPTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/CommandsS2CPTest.kt new file mode 100644 index 000000000..6e581ece6 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/CommandsS2CPTest.kt @@ -0,0 +1,50 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 + +import de.bixilon.kutil.cast.CastUtil.nullCast +import de.bixilon.kutil.cast.CastUtil.unsafeCast +import de.bixilon.minosoft.commands.nodes.CommandNode +import de.bixilon.minosoft.commands.nodes.NamedNode +import de.bixilon.minosoft.commands.nodes.RootNode +import org.testng.Assert.assertNotNull +import org.testng.annotations.Test + +@Test(groups = ["packet"]) +class CommandsS2CPTest { + private val children = CommandNode::class.java.getDeclaredField("children").apply { isAccessible = true } + private val RootNode.children: List get() = this@CommandsS2CPTest.children.get(this).unsafeCast() + + fun vanilla_op_1_19_3() { + val packet = PacketReadingTestUtil.read("commands/vanilla_op_1_19_3", "1.19.3", constructor = ::CommandsS2CP) + assertNotNull(packet.rootNode) + val help = packet.rootNode!!.children.find { it.nullCast()?.name == "help" } + assertNotNull(help) + } + + fun vanilla_op_1_15_2() { + val packet = PacketReadingTestUtil.read("commands/vanilla_op_1_15_2", "1.15.2", constructor = ::CommandsS2CP) + assertNotNull(packet.rootNode) + val help = packet.rootNode!!.children.find { it.nullCast()?.name == "help" } + assertNotNull(help) + } + + fun vanilla_op_1_20_1() { + val packet = PacketReadingTestUtil.read("commands/vanilla_op_1_20_1", "1.20.1", constructor = ::CommandsS2CP) + assertNotNull(packet.rootNode) + val help = packet.rootNode!!.children.find { it.nullCast()?.name == "help" } + assertNotNull(help) + } +} + diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/PacketReadingTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/PacketReadingTestUtil.kt new file mode 100644 index 000000000..964e0f15f --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/protocol/packets/s2c/play/PacketReadingTestUtil.kt @@ -0,0 +1,30 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 + +import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil +import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import de.bixilon.minosoft.protocol.packets.s2c.S2CPacket +import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer + +object PacketReadingTestUtil { + + fun read(name: String, version: String, connection: PlayConnection = ConnectionTestUtil.createConnection(version = version), constructor: (PlayInByteBuffer) -> T): T { + val data = PacketReadingTestUtil::class.java.getResourceAsStream("/packets/$name.bin")!!.readAllBytes() + + val buffer = PlayInByteBuffer(data, connection) + + return constructor.invoke(buffer) + } +} diff --git a/src/integration-test/resources/packets/commands/vanilla_op_1_15_2.bin b/src/integration-test/resources/packets/commands/vanilla_op_1_15_2.bin new file mode 100644 index 0000000000000000000000000000000000000000..b1b135f3e1f9fe13817e3363cc330c09db1c423c GIT binary patch literal 24981 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 literal 0 HcmV?d00001