container fixer, chest container type

This commit is contained in:
Moritz Zwerger 2023-10-12 19:32:08 +02:00
parent 35db62583a
commit 0f151e4a0b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
27 changed files with 132 additions and 40 deletions

View File

@ -65,7 +65,7 @@ object ContainerTestUtil {
private object GenericContainerFactory : ContainerFactory<Container> {
override val identifier: ResourceLocation = minosoft("test")
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Container {
return UnknownContainer(connection, type, title)
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* 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.
*
@ -17,5 +17,5 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation
@Deprecated("Will be removed")
object DefaultInventoryTypes {
val HORSE = "minecraft:EntityHorse".toResourceLocation()
val HORSE = "minecraft:horse".toResourceLocation()
}

View File

@ -62,7 +62,7 @@ class CraftingContainer(connection: PlayConnection, type: ContainerType, title:
)
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): CraftingContainer {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): CraftingContainer {
return CraftingContainer(connection, type, title)
}
}

View File

@ -123,7 +123,7 @@ class EnchantingContainer(connection: PlayConnection, type: ContainerType, title
PassiveInventorySection(ENCHANTING_SLOTS),
)
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): EnchantingContainer {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): EnchantingContainer {
return EnchantingContainer(connection, type, title)
}
}

View File

@ -177,7 +177,7 @@ class PlayerInventory(
HotbarSection(HOTBAR_OFFSET, false),
)
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): PlayerInventory {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): PlayerInventory {
Broken("Can not create player inventory!")
}
}

View File

@ -32,7 +32,7 @@ class UnknownContainer(
companion object : ContainerFactory<Container> {
override val identifier: ResourceLocation = minecraft("container")
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Container {
return UnknownContainer(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x1Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x1Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x1".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x1Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x1Container {
return Generic9x1Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x2Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x2Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x2".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x2Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x2Container {
return Generic9x2Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x3Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x3Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x3".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x3Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x3Container {
return Generic9x3Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x4Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x4Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x4".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x4Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x4Container {
return Generic9x4Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x5Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x5Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x5".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x5Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x5Container {
return Generic9x5Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class Generic9x6Container(connection: PlayConnection, type: ContainerType, title
companion object : ContainerFactory<Generic9x6Container> {
override val identifier: ResourceLocation = "minecraft:generic_9x6".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): Generic9x6Container {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): Generic9x6Container {
return Generic9x6Container(connection, type, title)
}
}

View File

@ -0,0 +1,39 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.container.types.generic.legacy
import de.bixilon.minosoft.data.container.types.generic.*
import de.bixilon.minosoft.data.registries.containers.ContainerFactory
import de.bixilon.minosoft.data.registries.containers.ContainerType
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
object ChestContainer : ContainerFactory<GenericContainer> {
override val identifier = minecraft("chest")
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): GenericContainer {
val factory = when (slots) {
9 -> Generic9x1Container
18 -> Generic9x2Container
27 -> Generic9x3Container
36 -> Generic9x4Container
45 -> Generic9x5Container
54 -> Generic9x6Container
else -> throw IllegalArgumentException("Invalid slot count for chest $slots")
}
return factory.build(connection, type, title, slots)
}
}

View File

@ -0,0 +1,31 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.container.types.generic.legacy
import de.bixilon.minosoft.data.container.types.generic.Generic9x3Container
import de.bixilon.minosoft.data.container.types.generic.GenericContainer
import de.bixilon.minosoft.data.registries.containers.ContainerFactory
import de.bixilon.minosoft.data.registries.containers.ContainerType
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
object ShulkerBoxContainer : ContainerFactory<GenericContainer> {
override val identifier = minecraft("shulker_box")
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): GenericContainer {
return Generic9x3Container(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class BlastFurnaceContainer(connection: PlayConnection, type: ContainerType, tit
companion object : ContainerFactory<BlastFurnaceContainer> {
override val identifier: ResourceLocation = "minecraft:blast_furnace".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): BlastFurnaceContainer {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): BlastFurnaceContainer {
return BlastFurnaceContainer(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class FurnaceContainer(connection: PlayConnection, type: ContainerType, title: C
companion object : ContainerFactory<FurnaceContainer> {
override val identifier: ResourceLocation = "minecraft:furnace".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): FurnaceContainer {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): FurnaceContainer {
return FurnaceContainer(connection, type, title)
}
}

View File

@ -25,7 +25,7 @@ class SmokerContainer(connection: PlayConnection, type: ContainerType, title: Ch
companion object : ContainerFactory<SmokerContainer> {
override val identifier: ResourceLocation = "minecraft:smoker".toResourceLocation()
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?): SmokerContainer {
override fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent?, slots: Int): SmokerContainer {
return SmokerContainer(connection, type, title)
}
}

View File

@ -20,5 +20,5 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
interface ContainerFactory<T : Container> : Identified {
fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent? = null): T
fun build(connection: PlayConnection, type: ContainerType, title: ChatComponent? = null, slots: Int): T
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* 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.
*
@ -17,6 +17,8 @@ import de.bixilon.minosoft.data.container.types.CraftingContainer
import de.bixilon.minosoft.data.container.types.EnchantingContainer
import de.bixilon.minosoft.data.container.types.PlayerInventory
import de.bixilon.minosoft.data.container.types.generic.*
import de.bixilon.minosoft.data.container.types.generic.legacy.ChestContainer
import de.bixilon.minosoft.data.container.types.generic.legacy.ShulkerBoxContainer
import de.bixilon.minosoft.data.container.types.processing.smelting.BlastFurnaceContainer
import de.bixilon.minosoft.data.container.types.processing.smelting.FurnaceContainer
import de.bixilon.minosoft.data.container.types.processing.smelting.SmokerContainer
@ -25,18 +27,12 @@ import de.bixilon.minosoft.data.registries.factory.DefaultFactory
object DefaultContainerFactories : DefaultFactory<ContainerFactory<*>>(
PlayerInventory,
Generic9x1Container,
Generic9x2Container,
Generic9x3Container,
Generic9x4Container,
Generic9x5Container,
Generic9x6Container,
ChestContainer, ShulkerBoxContainer,
Generic9x1Container, Generic9x2Container, Generic9x3Container, Generic9x4Container, Generic9x5Container, Generic9x6Container,
CraftingContainer,
BlastFurnaceContainer,
FurnaceContainer,
SmokerContainer,
BlastFurnaceContainer, FurnaceContainer, SmokerContainer,
EnchantingContainer,
)

View File

@ -179,7 +179,7 @@ class Registries(
// id stuff
// id resource location stuff
worker += WorkerTask(this::containerType) { containerType.update(pixlyzerData["container_types"]?.toJsonObject(), version, this) }
worker += WorkerTask(this::containerType) { containerType.update(pixlyzerData["container_types", "container_type"]?.toJsonObject(), version, this) }
worker += WorkerTask(this::gameEvent) { gameEvent.update(pixlyzerData["game_events"]?.toJsonObject(), version, this) }
worker += WorkerTask(this::worldEvent) { worldEvent.update(pixlyzerData["world_events"]?.toJsonObject(), version, this) }
worker += WorkerTask(this::argumentType) { argumentType.update(pixlyzerData["argument_type"]?.toJsonObject(), version, this) }

View File

@ -14,10 +14,7 @@
package de.bixilon.minosoft.datafixer
import de.bixilon.minosoft.datafixer.enumeration.EntityDataTypesFixer
import de.bixilon.minosoft.datafixer.rls.BlockEntityFixer
import de.bixilon.minosoft.datafixer.rls.EntityAttributeFixer
import de.bixilon.minosoft.datafixer.rls.MotifFixer
import de.bixilon.minosoft.datafixer.rls.RegistryFixer
import de.bixilon.minosoft.datafixer.rls.*
object DataFixer {
val fixer = listOf(
@ -27,6 +24,7 @@ object DataFixer {
EntityAttributeFixer,
RegistryFixer,
MotifFixer,
ContainerTypeFixer,
)

View File

@ -0,0 +1,22 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.datafixer.rls
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
object ContainerTypeFixer : ResourceLocationFixer(minosoft("container_type")) {
fun ResourceLocation.fixContainerType() = fix(this)
}

View File

@ -29,7 +29,7 @@ data class ContainerClickC2SP(
val button: Int,
val actionId: Int,
val changes: Int2ObjectMap<ItemStack?>,
val floating: ItemStack?,
val item: ItemStack?,
) : PlayC2SPacket {
override fun write(buffer: PlayOutByteBuffer) {
@ -51,10 +51,10 @@ data class ContainerClickC2SP(
buffer.writeItemStack(value)
}
}
buffer.writeItemStack(floating)
buffer.writeItemStack(item)
}
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_OUT, LogLevels.VERBOSE) { "Container click (containerId=$containerId, revision=$revision, slot=$slot, action=$button, actionId=$actionId, changes=$changes, floating=$floating)" }
Log.log(LogMessageType.NETWORK_OUT, LogLevels.VERBOSE) { "Container click (containerId=$containerId, revision=$revision, slot=$slot, action=$button, actionId=$actionId, changes=$changes, item=$item)" }
}
}

View File

@ -16,6 +16,7 @@ import de.bixilon.minosoft.data.container.DefaultInventoryTypes
import de.bixilon.minosoft.data.container.types.PlayerInventory
import de.bixilon.minosoft.data.registries.containers.ContainerType
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.datafixer.rls.ContainerTypeFixer
import de.bixilon.minosoft.modding.event.events.container.ContainerOpenEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
@ -32,7 +33,7 @@ class OpenContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
val containerId = if (buffer.versionId <= V_1_14) buffer.readUnsignedByte() else buffer.readVarInt() // ToDo: This is completely guessed, it has changed between 1.13 and 1.14, same as #L38
val containerType: ContainerType = when {
buffer.versionId < V_14W03B -> buffer.connection.registries.containerType[buffer.readUnsignedByte()]
buffer.versionId < V_1_14 -> buffer.readLegacyRegistryItem(buffer.connection.registries.containerType)!! // TODO: version completely guessed
buffer.versionId < V_1_14 -> buffer.readLegacyRegistryItem(buffer.connection.registries.containerType, ContainerTypeFixer)!! // TODO: version completely guessed
else -> buffer.readRegistryItem(buffer.connection.registries.containerType)
}
val title: ChatComponent = buffer.readNbtChatComponent()
@ -50,7 +51,7 @@ class OpenContainerS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
return
}
val title = if (hasTitle) title else null
val container = containerType.factory.build(connection, containerType, title)
val container = containerType.factory.build(connection, containerType, title, slotCount)
connection.player.items.incomplete.remove(containerId)?.let {
for ((slot, stack) in it.slots) {

View File

@ -16,7 +16,7 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.entities.data.EntityData
import de.bixilon.minosoft.data.entities.entities.decoration.Painting
import de.bixilon.minosoft.datafixer.rls.MotifFixer.fixMotif
import de.bixilon.minosoft.datafixer.rls.MotifFixer
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
@ -40,7 +40,7 @@ class EntityPaintingS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
init {
val motif = if (buffer.versionId < ProtocolVersions.V_18W02A) {
buffer.connection.registries.motif[buffer.readResourceLocation().fixMotif()]!!
buffer.readLegacyRegistryItem(buffer.connection.registries.motif, MotifFixer)!!
} else {
buffer.readRegistryItem(buffer.connection.registries.motif)
}

View File

@ -33,6 +33,7 @@ import de.bixilon.minosoft.data.registries.registries.registry.Registry
import de.bixilon.minosoft.data.registries.registries.registry.RegistryItem
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.TextComponent
import de.bixilon.minosoft.datafixer.rls.ResourceLocationFixer
import de.bixilon.minosoft.protocol.PlayerPublicKey
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
@ -272,7 +273,7 @@ class PlayInByteBuffer : InByteBuffer {
return registry[readVarInt()]
}
fun <T : RegistryItem> readLegacyRegistryItem(registry: Registry<T>): T? {
fun <T : RegistryItem> readLegacyRegistryItem(registry: Registry<T>, fixer: ResourceLocationFixer? = null): T? {
return registry[readResourceLocation()]
}

View File

@ -0,0 +1,4 @@
{
"EntityHorse": "minecraft:horse",
"container": "chest"
}