diff --git a/common/src/main/kotlin/com/github/spigotbasics/common/MinecraftVersion.kt b/common/src/main/kotlin/com/github/spigotbasics/common/MinecraftVersion.kt index 28e16ff7..290c9d0f 100644 --- a/common/src/main/kotlin/com/github/spigotbasics/common/MinecraftVersion.kt +++ b/common/src/main/kotlin/com/github/spigotbasics/common/MinecraftVersion.kt @@ -13,6 +13,8 @@ data class MinecraftVersion( val patch: Int = 0, ) : Comparable { companion object { + val v1_20_6 = MinecraftVersion(1, 20, 6) + val v1_20_5 = MinecraftVersion(1, 20, 5) val v1_20_4 = MinecraftVersion(1, 20, 4) val v1_20_3 = MinecraftVersion(1, 20, 3) diff --git a/nms/aggregator/src/main/kotlin/com/github/spigotbasics/nms/NMSAggregator.kt b/nms/aggregator/src/main/kotlin/com/github/spigotbasics/nms/NMSAggregator.kt index 82362b89..2caf84da 100644 --- a/nms/aggregator/src/main/kotlin/com/github/spigotbasics/nms/NMSAggregator.kt +++ b/nms/aggregator/src/main/kotlin/com/github/spigotbasics/nms/NMSAggregator.kt @@ -2,6 +2,7 @@ package com.github.spigotbasics.nms import com.github.spigotbasics.common.MinecraftVersion import com.github.spigotbasics.nms.v1_20_4.NMSImpl_v1_20_4 +import com.github.spigotbasics.nms.v1_20_6.NMSImpl_v1_20_6 object NMSAggregator { fun getNmsFacade(version: MinecraftVersion): NMSFacade { @@ -10,6 +11,9 @@ object NMSAggregator { if (version in MinecraftVersion.v1_20_3..MinecraftVersion.v1_20_4) { return NMSImpl_v1_20_4() } + if (version in MinecraftVersion.v1_20_5..MinecraftVersion.v1_20_6) { + return NMSImpl_v1_20_6() + } } catch (t: Throwable) { t.printStackTrace() } diff --git a/nms/versions/1.20.4/build.gradle.kts b/nms/versions/1.20.4/build.gradle.kts index 16af0476..22d8c14e 100644 --- a/nms/versions/1.20.4/build.gradle.kts +++ b/nms/versions/1.20.4/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("basics.nms-module") - id("io.papermc.paperweight.userdev") version "1.5.11" + id("io.papermc.paperweight.userdev") version "1.7.0" } dependencies { diff --git a/nms/versions/1.20.6/build.gradle.kts b/nms/versions/1.20.6/build.gradle.kts new file mode 100644 index 00000000..4de550d3 --- /dev/null +++ b/nms/versions/1.20.6/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + id("basics.nms-module") + id("io.papermc.paperweight.userdev") version "1.7.0" +} + +dependencies { + paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT") +} diff --git a/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/MenuBuilderImpl.kt b/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/MenuBuilderImpl.kt new file mode 100644 index 00000000..177166fa --- /dev/null +++ b/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/MenuBuilderImpl.kt @@ -0,0 +1,82 @@ +package com.github.spigotbasics.nms.v1_20_6 + +import net.minecraft.core.BlockPos +import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.entity.player.Inventory +import net.minecraft.world.inventory.AbstractContainerMenu +import net.minecraft.world.inventory.AnvilMenu +import net.minecraft.world.inventory.CartographyTableMenu +import net.minecraft.world.inventory.ContainerLevelAccess +import net.minecraft.world.inventory.EnchantmentMenu +import net.minecraft.world.inventory.GrindstoneMenu +import net.minecraft.world.inventory.LoomMenu +import net.minecraft.world.inventory.MenuConstructor +import net.minecraft.world.inventory.SmithingMenu +import net.minecraft.world.inventory.StonecutterMenu +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.state.BlockState +import org.bukkit.event.inventory.InventoryType + +object MenuBuilderImpl { + private val builder = mutableMapOf() + private val titles = mutableMapOf() + + init { + builder[InventoryType.ANVIL] = worldAccess(::AnvilMenu) + builder[InventoryType.ENCHANTING] = worldAccess(::EnchantmentMenu) + builder[InventoryType.LOOM] = worldAccess(::LoomMenu) + builder[InventoryType.CARTOGRAPHY] = worldAccess(::CartographyTableMenu) + builder[InventoryType.GRINDSTONE] = worldAccess(::GrindstoneMenu) + builder[InventoryType.SMITHING] = worldAccess(::SmithingMenu) + builder[InventoryType.STONECUTTER] = worldAccess(::StonecutterMenu) + } + + init { + titles[InventoryType.ANVIL] = Component.translatable("container.repair") + titles[InventoryType.ENCHANTING] = Component.translatable("container.enchant") + titles[InventoryType.LOOM] = Component.translatable("container.loom") + titles[InventoryType.CARTOGRAPHY] = Component.translatable("container.cartography_table") + titles[InventoryType.GRINDSTONE] = Component.translatable("container.grindstone_title") + titles[InventoryType.SMITHING] = Component.translatable("container.upgrade") + titles[InventoryType.STONECUTTER] = Component.translatable("container.stonecutter") + } + + fun build( + serverPlayer: ServerPlayer, + inventoryType: InventoryType, + ): AbstractContainerMenu? { + return (builder[inventoryType] ?: return null).supply(serverPlayer, serverPlayer.inventory) + } + + fun title(inventoryType: InventoryType): Component? { + return titles[inventoryType] + } + + private fun interface ContainerProvider { + fun supply( + player: ServerPlayer, + playerInventory: Inventory, + ): AbstractContainerMenu + } + + private fun tile( + block: Block, + entity: (BlockPos, BlockState) -> MenuConstructor, + ): ContainerProvider { + return ContainerProvider { player, inventory -> + return@ContainerProvider entity.invoke(BlockPos.ZERO, block.defaultBlockState()) + .createMenu(player.nextContainerCounter(), inventory, player)!! + } + } + + private fun worldAccess(accessor: (Int, Inventory, ContainerLevelAccess) -> AbstractContainerMenu): ContainerProvider { + return ContainerProvider { player, inventory -> + return@ContainerProvider accessor.invoke( + player.nextContainerCounter(), + inventory, + ContainerLevelAccess.create(player.level(), player.blockPosition()), + ) + } + } +} diff --git a/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/NMSImpl_v1_20_6.kt b/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/NMSImpl_v1_20_6.kt new file mode 100644 index 00000000..2c2e85d9 --- /dev/null +++ b/nms/versions/1.20.6/src/main/kotlin/com/github/spigotbasics/nms/v1_20_6/NMSImpl_v1_20_6.kt @@ -0,0 +1,51 @@ +package com.github.spigotbasics.nms.v1_20_6 + +import com.github.spigotbasics.nms.NMSFacade +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket +import org.bukkit.Bukkit +import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.entity.HumanEntity +import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryOpenEvent +import org.bukkit.event.inventory.InventoryType +import org.bukkit.inventory.InventoryView +import java.lang.IllegalStateException + +class NMSImpl_v1_20_6 : NMSFacade { + override fun getTps(): DoubleArray { + val serverHandle = (Bukkit.getServer() as CraftServer).handle.server + return doubleArrayOf(serverHandle.tps1.average, serverHandle.tps5.average, serverHandle.tps15.average) + } + + override fun openWorkbench( + entity: HumanEntity, + type: InventoryType, + ): InventoryView? { + if (entity !is Player) { + throw IllegalStateException("this player does not have a connection so no packets could be sent") + } + + val serverPlayer = (entity as CraftPlayer).handle + + val resultMenu = + MenuBuilderImpl.build(serverPlayer, type) + ?: throw IllegalArgumentException("The given inventory type can not be used to create a workbench") + resultMenu.title = MenuBuilderImpl.title(type) + ?: throw IllegalArgumentException("the given inventory title was not found with the specified workbench") + resultMenu.checkReachable = false + + // Now that menu setup is done we will call the intended event in a much less naive manner as to support components + val event = InventoryOpenEvent(resultMenu.bukkitView) + Bukkit.getPluginManager().callEvent(event) + if (event.isCancelled) { + return null + } + + val menuType = resultMenu.type + serverPlayer.connection.send(ClientboundOpenScreenPacket(resultMenu.containerId, menuType, resultMenu.title)) + serverPlayer.containerMenu = resultMenu + serverPlayer.initMenu(resultMenu) + return resultMenu.bukkitView + } +}