From 32c17aa3ae7de1cd887aa522848a83a1045ac4dd Mon Sep 17 00:00:00 2001 From: Auxilor Date: Sun, 28 Nov 2021 10:59:35 +0000 Subject: [PATCH] 1.18 work --- build.gradle.kts | 1 + eco-core/core-nms/v1_18_R1/build.gradle.kts | 18 ++ .../spigot/proxy/v1_18_R1/AutoCraft.kt | 15 ++ .../spigot/proxy/v1_18_R1/BlockBreak.kt | 14 ++ .../spigot/proxy/v1_18_R1/ChatComponent.kt | 93 +++++++++ .../proxy/v1_18_R1/FastItemStackFactory.kt | 12 ++ .../internal/spigot/proxy/v1_18_R1/Skull.kt | 44 ++++ .../eco/internal/spigot/proxy/v1_18_R1/TPS.kt | 11 + .../spigot/proxy/v1_18_R1/VillagerTrade.kt | 41 ++++ .../proxy/v1_18_R1/fast/FastItemStackUtils.kt | 17 ++ .../proxy/v1_18_R1/fast/NMSFastItemStack.kt | 191 ++++++++++++++++++ settings.gradle.kts | 1 + 12 files changed, 458 insertions(+) create mode 100644 eco-core/core-nms/v1_18_R1/build.gradle.kts create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/AutoCraft.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/BlockBreak.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/ChatComponent.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/FastItemStackFactory.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/Skull.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/TPS.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/VillagerTrade.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/FastItemStackUtils.kt create mode 100644 eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/NMSFastItemStack.kt diff --git a/build.gradle.kts b/build.gradle.kts index c52e6b9b..c0dc4cbc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { implementation(project(":eco-core:core-backend")) implementation(project(":eco-core:core-nms:v1_16_R3")) implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf")) + implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf")) } allprojects { diff --git a/eco-core/core-nms/v1_18_R1/build.gradle.kts b/eco-core/core-nms/v1_18_R1/build.gradle.kts new file mode 100644 index 00000000..d53ed328 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("io.papermc.paperweight.userdev") version "1.3.0-SNAPSHOT" +} + +group = "com.willfp" +version = rootProject.version + +dependencies { + paperDevBundle("1.18-rc3-R0.1-SNAPSHOT") + compileOnly("net.kyori:adventure-api:4.9.1") + compileOnly("net.kyori:adventure-text-serializer-gson:4.8.1") +} + +tasks { + build { + dependsOn(reobfJar) + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/AutoCraft.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/AutoCraft.kt new file mode 100644 index 00000000..20394a47 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/AutoCraft.kt @@ -0,0 +1,15 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.internal.spigot.proxy.AutoCraftProxy +import net.minecraft.network.protocol.game.ClientboundPlaceGhostRecipePacket +import net.minecraft.resources.ResourceLocation + +class AutoCraft : AutoCraftProxy { + override fun modifyPacket(packet: Any) { + val recipePacket = packet as ClientboundPlaceGhostRecipePacket + val fKey = recipePacket.javaClass.getDeclaredField("b") + fKey.isAccessible = true + val key = fKey[recipePacket] as ResourceLocation + fKey[recipePacket] = ResourceLocation(key.namespace, key.path + "_displayed") + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/BlockBreak.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/BlockBreak.kt new file mode 100644 index 00000000..a8f5ba33 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/BlockBreak.kt @@ -0,0 +1,14 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy +import org.bukkit.block.Block +import org.bukkit.entity.Player + +class BlockBreak : BlockBreakProxy { + override fun breakBlock( + player: Player, + block: Block + ) { + player.breakBlock(block) + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/ChatComponent.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/ChatComponent.kt new file mode 100644 index 00000000..8a3d40fe --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/ChatComponent.kt @@ -0,0 +1,93 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.core.display.Display +import com.willfp.eco.internal.spigot.proxy.ChatComponentProxy +import net.kyori.adventure.nbt.api.BinaryTagHolder +import net.kyori.adventure.text.BuildableComponent +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TranslatableComponent +import net.kyori.adventure.text.event.HoverEvent +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer +import net.minecraft.nbt.TagParser +import org.bukkit.Material +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack + +@Suppress("UNCHECKED_CAST") +class ChatComponent : ChatComponentProxy { + private val gsonComponentSerializer = GsonComponentSerializer.gson() + + override fun modifyComponent(obj: Any, player: Player): Any { + if (obj !is net.minecraft.network.chat.Component) { + return obj + } + + val component = gsonComponentSerializer.deserialize( + net.minecraft.network.chat.Component.Serializer.toJson( + obj + ) + ).asComponent() as BuildableComponent<*, *> + + val newComponent = modifyBaseComponent(component, player) + + return net.minecraft.network.chat.Component.Serializer.fromJson( + gsonComponentSerializer.serialize(newComponent.asComponent()) + ) ?: obj + } + + private fun modifyBaseComponent(baseComponent: Component, player: Player): Component { + var component = baseComponent + + if (component is TranslatableComponent) { + val args = mutableListOf() + for (arg in component.args()) { + args.add(modifyBaseComponent(arg, player)) + } + component = component.args(args) + } + + val children = mutableListOf() + for (child in component.children()) { + children.add(modifyBaseComponent(child, player)) + } + component = component.children(children) + + val hoverEvent: HoverEvent = component.style().hoverEvent() as HoverEvent? ?: return component + + val showItem = hoverEvent.value() + + if (showItem !is HoverEvent.ShowItem) { + return component + } + + val newShowItem = showItem.nbt( + BinaryTagHolder.of( + CraftItemStack.asNMSCopy( + Display.display( + CraftItemStack.asBukkitCopy( + CraftItemStack.asNMSCopy( + ItemStack( + Material.matchMaterial( + showItem.item() + .toString() + ) ?: return component, + showItem.count() + ) + ).apply { + this.tag = TagParser.parseTag( + showItem.nbt()?.string() ?: return component + ) ?: return component + } + ), + player + ) + ).orCreateTag.toString() + ) + ) + + val newHover = hoverEvent.value(newShowItem) + val style = component.style().hoverEvent(newHover) + return component.style(style) + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/FastItemStackFactory.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/FastItemStackFactory.kt new file mode 100644 index 00000000..7e572b6e --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/FastItemStackFactory.kt @@ -0,0 +1,12 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.core.fast.FastItemStack +import com.willfp.eco.internal.spigot.proxy.v1_17_R1.fast.NMSFastItemStack +import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy +import org.bukkit.inventory.ItemStack + +class FastItemStackFactory : FastItemStackFactoryProxy { + override fun create(itemStack: ItemStack): FastItemStack { + return NMSFastItemStack(itemStack) + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/Skull.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/Skull.kt new file mode 100644 index 00000000..0a32c185 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/Skull.kt @@ -0,0 +1,44 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.mojang.authlib.GameProfile +import com.mojang.authlib.properties.Property +import com.willfp.eco.internal.spigot.proxy.SkullProxy +import org.bukkit.inventory.meta.SkullMeta +import java.lang.reflect.Field +import java.lang.reflect.Method +import java.util.UUID + +class Skull : SkullProxy { + private lateinit var setProfile: Method + private lateinit var profile: Field + + override fun setSkullTexture( + meta: SkullMeta, + base64: String + ) { + if (!this::setProfile.isInitialized) { + setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java) + setProfile.isAccessible = true + } + val uuid = UUID( + base64.substring(base64.length - 20).hashCode().toLong(), + base64.substring(base64.length - 10).hashCode().toLong() + ) + val profile = GameProfile(uuid, "eco") + profile.properties.put("textures", Property("textures", base64)) + setProfile.invoke(meta, profile) + } + + override fun getSkullTexture( + meta: SkullMeta + ): String? { + if (!this::profile.isInitialized) { + profile = meta.javaClass.getDeclaredField("profile") + profile.isAccessible = true + } + val profile = profile[meta] as GameProfile? ?: return null + val properties = profile.properties ?: return null + val prop = properties["textures"] ?: return null + return prop.toMutableList().firstOrNull()?.name + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/TPS.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/TPS.kt new file mode 100644 index 00000000..22dcc209 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/TPS.kt @@ -0,0 +1,11 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.internal.spigot.proxy.TPSProxy +import org.bukkit.Bukkit +import org.bukkit.craftbukkit.v1_17_R1.CraftServer + +class TPS : TPSProxy { + override fun getTPS(): Double { + return (Bukkit.getServer() as CraftServer).handle.server.recentTps[0] + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/VillagerTrade.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/VillagerTrade.kt new file mode 100644 index 00000000..e65a37ea --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/VillagerTrade.kt @@ -0,0 +1,41 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1 + +import com.willfp.eco.core.display.Display +import com.willfp.eco.internal.spigot.proxy.VillagerTradeProxy +import net.minecraft.world.item.trading.MerchantOffer +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe +import org.bukkit.entity.Player +import org.bukkit.inventory.MerchantRecipe +import java.lang.reflect.Field + +class VillagerTrade : VillagerTradeProxy { + private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle") + + override fun displayTrade( + recipe: MerchantRecipe, + player: Player + ): MerchantRecipe { + val oldRecipe = recipe as CraftMerchantRecipe + val newRecipe = CraftMerchantRecipe( + Display.display(recipe.getResult().clone(), player), + recipe.getUses(), + recipe.getMaxUses(), + recipe.hasExperienceReward(), + recipe.getVillagerExperience(), + recipe.getPriceMultiplier() + ) + for (ingredient in recipe.getIngredients()) { + newRecipe.addIngredient(Display.display(ingredient.clone(), player)) + } + getHandle(newRecipe).specialPriceDiff = getHandle(oldRecipe).specialPriceDiff + return newRecipe + } + + private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer { + return handle[recipe] as MerchantOffer + } + + init { + handle.isAccessible = true + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/FastItemStackUtils.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/FastItemStackUtils.kt new file mode 100644 index 00000000..c91ca144 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/FastItemStackUtils.kt @@ -0,0 +1,17 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast + +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack +import org.bukkit.inventory.ItemStack +import java.lang.reflect.Field + +private val field: Field = CraftItemStack::class.java.getDeclaredField("handle").apply { + isAccessible = true +} + +fun ItemStack.getNMSStack(): net.minecraft.world.item.ItemStack { + return if (this !is CraftItemStack) { + CraftItemStack.asNMSCopy(this) + } else { + field[this] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(this) + } +} \ No newline at end of file diff --git a/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/NMSFastItemStack.kt b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/NMSFastItemStack.kt new file mode 100644 index 00000000..cd7a1445 --- /dev/null +++ b/eco-core/core-nms/v1_18_R1/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/v1_18_R1/fast/NMSFastItemStack.kt @@ -0,0 +1,191 @@ +package com.willfp.eco.internal.spigot.proxy.v1_18_R1.fast + +import com.willfp.eco.internal.fast.EcoFastItemStack +import com.willfp.eco.util.StringUtils +import net.minecraft.nbt.CompoundTag +import net.minecraft.nbt.ListTag +import net.minecraft.nbt.StringTag +import net.minecraft.world.item.EnchantedBookItem +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack +import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers +import org.bukkit.craftbukkit.v1_17_R1.util.CraftNamespacedKey +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.ItemFlag +import kotlin.experimental.and + +class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack( + itemStack.getNMSStack(), itemStack +) { + private var loreCache: List? = null + + override fun getEnchantmentsOnItem(checkStored: Boolean): Map { + val enchantmentNBT = + if (checkStored && handle.item === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments( + handle + ) else handle.enchantmentTags + val foundEnchantments: MutableMap = HashMap() + for (base in enchantmentNBT) { + val compound = base as CompoundTag + val key = compound.getString("id") + val level = ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt() + val found = Enchantment.getByKey(CraftNamespacedKey.fromStringOrNull(key)) + if (found != null) { + foundEnchantments[found] = level + } + } + return foundEnchantments + } + + override fun getLevelOnItem( + enchantment: Enchantment, + checkStored: Boolean + ): Int { + val enchantmentNBT = + if (checkStored && handle.item === Items.ENCHANTED_BOOK) EnchantedBookItem.getEnchantments( + handle + ) else handle.enchantmentTags + for (base in enchantmentNBT) { + val compound = base as CompoundTag + val key = compound.getString("id") + if (key != enchantment.key.toString()) { + continue + } + return ('\uffff'.code.toShort() and compound.getShort("lvl")).toInt() + } + return 0 + } + + override fun setLore(lore: List?) { + loreCache = null + val jsonLore: MutableList = ArrayList() + + if (lore != null) { + for (s in lore) { + jsonLore.add(StringUtils.legacyToJson(s)) + } + } + + val displayTag = handle.getOrCreateTagElement("display") + + if (!displayTag.contains("Lore")) { + displayTag.put("Lore", ListTag()) + } + + val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING) + + loreTag.clear() + + for (s in jsonLore) { + loreTag.add(StringTag.valueOf(s)) + } + + apply() + } + + override fun getLore(): List { + if (loreCache != null) { + return loreCache as List + } + + val lore: MutableList = ArrayList() + + for (s in getLoreJSON()) { + lore.add(StringUtils.jsonToLegacy(s)) + } + + loreCache = lore + return lore + } + + private fun getLoreJSON(): List { + val displayTag = handle.getTagElement("display") ?: return emptyList() + return if (displayTag.contains("Lore")) { + val loreTag = displayTag.getList("Lore", CraftMagicNumbers.NBT.TAG_STRING) + val lore: MutableList = ArrayList(loreTag.size) + + for (i in loreTag.indices) { + lore.add(loreTag.getString(i)) + } + + lore + } else { + emptyList() + } + } + + override fun addItemFlags(vararg hideFlags: ItemFlag) { + for (flag in hideFlags) { + this.flagBits = this.flagBits or getBitModifier(flag) + } + + apply() + } + + override fun removeItemFlags(vararg hideFlags: ItemFlag) { + for (flag in hideFlags) { + this.flagBits = this.flagBits and getBitModifier(flag) + } + + apply() + } + + override fun getItemFlags(): MutableSet { + val flags = mutableSetOf() + + var flagArr: Array + val size = ItemFlag.values().also { flagArr = it }.size + + for (i in 0 until size) { + val flag = flagArr[i] + if (this.hasItemFlag(flag)) { + flags.add(flag) + } + } + + return flags + } + + override fun hasItemFlag(flag: ItemFlag): Boolean { + val bitModifier = getBitModifier(flag) + return this.flagBits and bitModifier == bitModifier + } + + private var flagBits: Int + get() = + if (handle.hasTag() && handle.tag!!.contains( + "HideFlags", + 99 + ) + ) handle.tag!!.getInt("HideFlags") else 0 + set(value) = + handle.orCreateTag.putInt("HideFlags", value) + + override fun getRepairCost(): Int { + return handle.baseRepairCost + } + + override fun setRepairCost(cost: Int) { + handle.setRepairCost(cost) + } + + override fun equals(other: Any?): Boolean { + if (other !is NMSFastItemStack) { + return false + } + + return other.hashCode() == this.hashCode() + } + + override fun hashCode(): Int { + return handle.tag?.hashCode() ?: 0b00010101 * 31 + Item.getId(handle.item) + } + + private fun apply() { + if (bukkit !is CraftItemStack) { + bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta + } + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index a291ae86..234a096f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,6 +13,7 @@ include(":eco-core") include(":eco-core:core-nms") include(":eco-core:core-nms:v1_16_R3") include(":eco-core:core-nms:v1_17_R1") +include(":eco-core:core-nms:v1_18_R1") include(":eco-core:core-proxy") include(":eco-core:core-plugin") include(":eco-core:core-backend") \ No newline at end of file