Compare commits

..

16 Commits

Author SHA1 Message Date
Will FP
a55407be51 Added 1.21.6 support 2025-06-20 10:20:03 +01:00
Will FP
1ffadf8927 Merge pull request #399
Fix FabledSkyBlock errors on new versions of the plugin
2025-06-07 14:58:54 +01:00
xsmeths
12f8117252 Update stripped FSB 4.2.2 lib jar (compile only) 2025-06-07 09:40:53 +01:00
xsmeths
57c365c158 Add stripped FSB 4.2.2 lib jar (compile only) 2025-06-07 08:30:00 +01:00
smeths
7bd6e4be90 Update AntigriefFabledSkyBlock.kt
change import to match newest versions of FSB
2025-06-07 03:49:59 +01:00
Will FP
ba9210e203 Updated cache 2025-06-03 15:17:00 +01:00
Will FP
a2a3ade0ae Cleaned up PacketWindowItems.kt 2025-06-03 15:15:42 +01:00
Will FP
08455b3694 Fixed 1.21.5 support 2025-06-02 15:01:33 +01:00
Will FP
76144013d5 Added 1.21.5 support, bumped version 2025-06-02 13:52:11 +01:00
Will FP
bde705dbf5 Updated to 6.75.2 2025-02-01 16:10:24 +00:00
Will FP
48ca42211d Merge remote-tracking branch 'origin/master'
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/antigrief/AntigriefHuskClaims.kt
2025-02-01 16:10:17 +00:00
Will FP
af5a325527 Fixed Entity lookup throwing errors when passing in 'unknown' 2025-02-01 16:10:07 +00:00
Will FP
eb0d6b2d27 Optimised imports 2025-02-01 16:09:54 +00:00
Will FP
69d21550b3 Merge pull request #386 from Exanthiax/husktowns
Updated HuskClaims/HuskTowns Integration
2025-01-31 11:40:38 +00:00
Exanthiax
0bcd688345 fix oopsie 2025-01-26 18:43:51 +00:00
Exanthiax
25de30142b Updated HuskClaims/HuskTowns Integration
Updated API versions and classes to newest versions.
2025-01-25 21:12:29 +00:00
88 changed files with 2173 additions and 126 deletions

View File

@@ -21,7 +21,7 @@ jobs:
java-version: 21
- name: Setup build cache
uses: actions/cache@v2.1.6
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}

View File

@@ -19,7 +19,7 @@ jobs:
java-version: 21
- name: Setup build cache
uses: actions/cache@v2.1.6
uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}

View File

@@ -36,6 +36,8 @@ dependencies {
implementation(project(path = ":eco-core:core-nms:v1_21", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21_3", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21_4", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21_5", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_21_6", configuration = "reobf"))
}
allprojects {

View File

@@ -37,8 +37,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

View File

@@ -6,7 +6,6 @@ import com.willfp.eco.core.tuples.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

View File

@@ -111,6 +111,11 @@ public final class Entities {
} catch (IllegalArgumentException e) {
return new EmptyTestableEntity();
}
if (type.getEntityClass() == null) {
return new EmptyTestableEntity();
}
entity = new SimpleTestableEntity(type);
} else {
String namespace = split[0];

View File

@@ -11,7 +11,6 @@ import org.bukkit.entity.Raider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

View File

@@ -7,9 +7,6 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle antigrief integrations.
*/

View File

@@ -3,9 +3,6 @@ package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle custom item integrations.
*/

View File

@@ -5,9 +5,6 @@ import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle mcmmo integrations.
*/

View File

@@ -6,10 +6,51 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents a packet.
*
* @param handle The NMS handle.
*/
public record Packet(@NotNull Object handle) {
public class Packet {
/**
* The packet handle.
*/
private Object handle;
/**
* Create a new packet.
*
* @param handle The packet handle.
*/
public Packet(@NotNull final Object handle) {
this.handle = handle;
}
/**
* Get the packet handle.
*
* @return The packet handle.
*/
public Object getHandle() {
return handle;
}
/**
* Set the packet handle.
*
* @param handle The packet handle.
*/
public void setHandle(@NotNull final Object handle) {
this.handle = handle;
}
/**
* Get the packet handle, compatible with the old record-based packet system.
*
* @return The packet handle.
* @deprecated Use {@link #getHandle()} instead.
*/
@Deprecated
public Object handle() {
return handle;
}
/**
* Send to a player.
*

View File

@@ -31,7 +31,9 @@ public final class ProxyConstants {
"v1_20_R3",
"v1_21",
"v1_21_3",
"v1_21_4"
"v1_21_4",
"v1_21_5",
"v1_21_6"
);
private ProxyConstants() {

View File

@@ -3,10 +3,7 @@
package com.willfp.eco.core.entities
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack
/** @see EntityController.getFor */
val <T : Mob> T.controller: EntityController<T>

View File

@@ -4,8 +4,6 @@ import com.willfp.eco.core.entities.args.EntityArgParseResult
import com.willfp.eco.core.entities.args.EntityArgParser
import org.bukkit.attribute.Attribute
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Phantom
import org.bukkit.entity.Slime
object EntityArgParserScale : EntityArgParser {
override fun parseArguments(args: Array<out String>): EntityArgParseResult? {

View File

@@ -9,7 +9,6 @@ import com.willfp.eco.core.packet.PacketPriority
import org.bukkit.Bukkit
import org.bukkit.event.HandlerList
import org.bukkit.event.Listener
import java.lang.Exception
private class RegisteredPacketListener(

View File

@@ -2,9 +2,7 @@ package com.willfp.eco.internal.items
import com.willfp.eco.internal.items.templates.ValueArgParser
import com.willfp.eco.util.StringUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
object ArgParserName : ValueArgParser<String>("name") {
override fun parse(arg: String): String {

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.items.templates
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.util.StringUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate

View File

@@ -1,5 +1,5 @@
plugins {
id("io.papermc.paperweight.userdev") version "2.0.0-beta.14" apply false
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.spigot.proxy.common.ai.target
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackable
import com.willfp.eco.core.lookup.matches
import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.toBukkitEntity
import net.minecraft.world.entity.LivingEntity

View File

@@ -23,7 +23,7 @@ class EcoChannelDuplexHandler(
event.handleReceive()
if (!event.isCancelled) {
super.channelRead(ctx, msg)
super.channelRead(ctx, event.packet.handle)
}
} else {
super.channelRead(ctx, msg)
@@ -39,7 +39,7 @@ class EcoChannelDuplexHandler(
event.handleSend()
if (!event.isCancelled) {
super.write(ctx, msg, promise)
super.write(ctx, event.packet.handle, promise)
}
} else {
super.write(ctx, msg, promise)

View File

@@ -15,7 +15,7 @@ import org.bukkit.inventory.ItemStack
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
class PacketWindowItems(
open class PacketWindowItems(
private val plugin: EcoPlugin
) : PacketListener {
private val lastKnownWindowIDs = ConcurrentHashMap<UUID, Int>()
@@ -52,7 +52,7 @@ class PacketWindowItems(
}
private fun modifyWindowItems(
protected fun modifyWindowItems(
itemStacks: MutableList<ItemStack>,
windowId: Int,
player: Player

View File

@@ -14,29 +14,22 @@ import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.toComponent
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.Style
import net.kyori.adventure.text.format.TextColor
import net.kyori.adventure.text.format.TextDecoration
import net.minecraft.core.Holder
import net.minecraft.core.component.DataComponentType
import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.Registries
import net.minecraft.nbt.CompoundTag
import net.minecraft.util.Unit
import net.minecraft.world.item.component.CustomData
import net.minecraft.world.item.component.CustomModelData
import net.minecraft.world.item.component.ItemLore
import net.minecraft.world.item.enchantment.ItemEnchantments
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftRegistry
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import kotlin.math.max
import kotlin.math.min
private val unstyledComponent = Component.empty().style {
it.color(null).decoration(TextDecoration.ITALIC, false)
@@ -151,7 +144,7 @@ open class NewEcoFastItemStack(
override fun getDisplayName(): String = displayNameComponent.toLegacy()
private fun <T> net.minecraft.world.item.ItemStack.modifyComponent(
protected fun <T> net.minecraft.world.item.ItemStack.modifyComponent(
component: DataComponentType<T>,
modifier: (T) -> T
) {

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R1
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
import com.willfp.eco.internal.spigot.proxy.common.toMaterial
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser

View File

@@ -5,7 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import io.netty.channel.Channel
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.core.registries.BuiltInRegistries
@@ -13,7 +12,6 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.server.network.ServerGamePacketListenerImpl
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Bukkit

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R2
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack

View File

@@ -4,7 +4,6 @@ import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor

View File

@@ -4,16 +4,13 @@ import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftLivingEntity
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftMob
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import java.util.Optional

View File

@@ -4,16 +4,13 @@ import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftLivingEntity
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftMob
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import java.util.Optional

View File

@@ -5,7 +5,6 @@ import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import org.bukkit.Location
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld
import org.bukkit.entity.Entity
import org.bukkit.entity.EntityType
import org.bukkit.entity.Zombie
class DummyEntityFactory : DummyEntityFactoryProxy {

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_20_R3
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.item.ContinuallyAppliedPersistentDataContainer
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack

View File

@@ -3,13 +3,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_21
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import net.minecraft.core.Registry
import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import net.minecraft.world.item.component.CustomModelData
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -3,10 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_21_3
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_21_3
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems

View File

@@ -3,11 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_21_4
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import net.minecraft.core.Registry
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceKey
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_21_4
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketAutoRecipe
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
object NewItemsPacketSetCreativeSlot : PacketListener {

View File

@@ -0,0 +1,52 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("io.papermc.paperweight.userdev")
}
group = "com.willfp"
version = rootProject.version
dependencies {
implementation(project(":eco-core:core-nms:modern"))
implementation(project(":eco-core:core-nms:common"))
paperweight.paperDevBundle("1.21.5-R0.1-SNAPSHOT")
implementation("net.kyori:adventure-text-minimessage:4.11.0") {
version {
strictly("4.11.0")
}
exclude(group = "net.kyori", module = "adventure-api")
}
}
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
shadowJar {
relocate(
"com.willfp.eco.internal.spigot.proxy.common",
"com.willfp.eco.internal.spigot.proxy.v1_21_5.common"
)
relocate(
"net.kyori.adventure.text.minimessage",
"com.willfp.eco.internal.spigot.proxy.v1_21_5.minimessage"
)
}
compileJava {
options.release.set(21)
}
compileKotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.command.PluginCommandBase
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.SimpleCommandMap
import org.bukkit.craftbukkit.CraftServer
import java.lang.reflect.Field
class BukkitCommands : BukkitCommandsProxy {
private val knownCommandsField: Field by lazy {
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
.apply {
isAccessible = true
}
}
@Suppress("UNCHECKED_CAST")
private val knownCommands: MutableMap<String, Command>
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
override fun getCommandMap(): SimpleCommandMap {
return (Bukkit.getServer() as CraftServer).commandMap
}
override fun syncCommands() {
(Bukkit.getServer() as CraftServer).syncCommands()
}
override fun unregisterCommand(command: PluginCommandBase) {
knownCommands.remove(command.name)
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
}
}

View File

@@ -0,0 +1,171 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.entity.CraftMob
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.inventory.CraftMetaArmor
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.craftbukkit.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy {
override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl)
plugin.onEnable {
plugin.eventManager.registerListener(PacketInjectorListener)
}
}
object CommonsProviderImpl : CommonsProvider {
private val cisHandle: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
private val pdcRegsitry = CraftMetaArmor::class.java
.superclass // Access CraftMetaItem
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = 8
override fun toPathfinderMob(mob: Mob): PathfinderMob? {
val craft = mob as? CraftMob ?: return null
return craft.handle as? PathfinderMob
}
override fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation =
CraftNamespacedKey.toMinecraft(namespacedKey)
override fun asNMSStack(itemStack: ItemStack): net.minecraft.world.item.ItemStack {
return if (itemStack !is CraftItemStack) {
CraftItemStack.asNMSCopy(itemStack)
} else {
cisHandle[itemStack] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(itemStack)
}
}
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asCraftMirror(itemStack)
}
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {
if (itemStack !is CraftItemStack) {
itemStack.itemMeta = CraftItemStack.asCraftMirror(nmsStack).itemMeta
}
}
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.keySet()
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").get().toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.keySet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.remove(DataComponents.CUSTOM_DATA)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
override fun materialToItem(material: Material): Item =
BuiltInRegistries.ITEM.getOptional(material.key.toResourceLocation())
.orElseThrow { IllegalArgumentException("Material is not item!") }
override fun itemToMaterial(item: Item) =
Material.getMaterial(BuiltInRegistries.ITEM.getKey(item).path.uppercase())
?: throw IllegalArgumentException("Invalid material!")
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
val json = JSONComponentSerializer.json().serialize(component)
val holderLookupProvider = (Bukkit.getServer() as CraftServer).server.registryAccess()
return net.minecraft.network.chat.Component.Serializer.fromJson(json, holderLookupProvider)!!
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
listOf(
SynchedEntityData.DataValue.create(displayNameAccessor, Optional.of(nmsComponent)),
SynchedEntityData.DataValue.create(customNameVisibleAccessor, visible)
)
)
player.sendPacket(Packet(packet))
}
}

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.internal.entities.EcoDummyEntity
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import org.bukkit.Location
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.entity.Entity
import org.bukkit.entity.Zombie
class DummyEntityFactory : DummyEntityFactoryProxy {
override fun createDummyEntity(location: Location): Entity {
val world = location.world as CraftWorld
return EcoDummyEntity(world.createEntity(location, Zombie::class.java))
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.v1_21_5.entity.EcoEntityController
import org.bukkit.entity.Mob
class EntityControllerFactory : EntityControllerFactoryProxy {
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
return EcoEntityController(entity)
}
}

View File

@@ -0,0 +1,91 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
import java.lang.reflect.Field
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
private val registry: CraftPersistentDataTypeRegistry
init {
/*
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
And getting it would mean more janky reflection
*/
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
val pdc = item.itemMeta!!.persistentDataContainer
// Cross-version compatibility:
val registryField: Field = try {
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
} catch (e: NoSuchFieldException) {
CraftPersistentDataContainer::class.java.superclass.getDeclaredField("registry")
}
this.registry = registryField
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
}
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
private val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] =
registry.wrap(dataType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract<T, Tag>(dataType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import com.willfp.eco.internal.spigot.proxy.v1_21_5.item.NewerEcoFastItemStack
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {
override fun create(itemStack: ItemStack): FastItemStack {
return NewerEcoFastItemStack(itemStack)
}
}

View File

@@ -0,0 +1,33 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.minimessage.MiniMessage
class MiniMessageTranslator : MiniMessageTranslatorProxy {
override fun format(message: String): String {
var mut = message
val startsWithPrefix = mut.startsWith(Display.PREFIX)
if (startsWithPrefix) {
mut = mut.substring(2)
}
mut = mut.replace('§', '&')
val miniMessage = runCatching {
MiniMessage.miniMessage().deserialize(
mut
).toLegacy()
}.getOrNull() ?: mut
mut = if (startsWithPrefix) {
Display.PREFIX + miniMessage
} else {
miniMessage
}
return mut
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_21_5.packet.NewItemsPacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.v1_21_5.packet.NewItemsPacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.v1_21_5.packet.NewItemsPacketWindowItems
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun sendPacket(player: Player, packet: com.willfp.eco.core.packet.Packet) {
if (player !is CraftPlayer) {
return
}
val handle = packet.handle
if (handle !is Packet<*>) {
return
}
player.handle.connection.send(handle)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
// No PacketAutoRecipe for 1.21.3+ because recipes have been changed internally
return listOf(
PacketHeldItemSlot,
NewItemsPacketOpenWindowMerchant,
NewItemsPacketSetCreativeSlot,
PacketSetSlot,
NewItemsPacketWindowItems(plugin)
)
}
}

View File

@@ -0,0 +1,81 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.mojang.serialization.Dynamic
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import net.minecraft.server.MinecraftServer
import net.minecraft.util.datafix.fixes.References
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
private val registryAccess = (Bukkit.getServer() as CraftServer).server.registryAccess()
class SNBTConverter : SNBTConverterProxy {
private fun parseItemSNBT(snbt: String): CompoundTag? {
val nbt = runCatching { TagParser.parseCompoundFully(snbt) }.getOrNull() ?: return null
val dataVersion = if (nbt.contains("DataVersion")) {
nbt.getInt("DataVersion").get()
} else null
// If the data version is the same as the server's data version, we don't need to fix it
if (dataVersion == CraftMagicNumbers.INSTANCE.dataVersion) {
return nbt
}
return MinecraftServer.getServer().fixerUpper.update(
References.ITEM_STACK,
Dynamic(NbtOps.INSTANCE, nbt),
dataVersion ?: 3700, // 3700 is the 1.20.4 data version
CraftMagicNumbers.INSTANCE.dataVersion
).value as CompoundTag
}
override fun fromSNBT(snbt: String): ItemStack? {
val tag = parseItemSNBT(snbt) ?: return null
val nms = net.minecraft.world.item.ItemStack.parse(registryAccess, tag).orElse(null) ?: return null
return CraftItemStack.asBukkitCopy(nms)
}
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nms.save(registryAccess) as CompoundTag
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
}
override fun makeSNBTTestable(snbt: String): TestableItem {
val tag = parseItemSNBT(snbt) ?: return EmptyTestableItem()
val nms = net.minecraft.world.item.ItemStack.parse(registryAccess, tag).orElse(null)
?: return EmptyTestableItem()
tag.remove("Count")
return SNBTTestableItem(CraftItemStack.asBukkitCopy(nms), tag)
}
class SNBTTestableItem(
private val item: ItemStack,
private val tag: CompoundTag
) : TestableItem {
override fun matches(itemStack: ItemStack?): Boolean {
if (itemStack == null) {
return false
}
val nms = CraftItemStack.asNMSCopy(itemStack)
val nmsTag = nms.save(registryAccess) as CompoundTag
nmsTag.remove("Count")
return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type
}
override fun getItem(): ItemStack = item
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.texture
import org.bukkit.inventory.meta.SkullMeta
class Skull : SkullProxy {
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? = meta.texture
}

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5
import com.willfp.eco.internal.spigot.proxy.TPSProxy
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
class TPS : TPSProxy {
override fun getTPS(): Double {
return (Bukkit.getServer() as CraftServer).handle.server.tps1.average
}
}

View File

@@ -0,0 +1,95 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5.entity
import com.willfp.eco.core.entities.ai.CustomGoal
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.internal.spigot.proxy.common.ai.CustomGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.ai.getGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.toPathfinderMob
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.goal.Goal
import org.bukkit.entity.Mob
class EcoEntityController<T : Mob>(
private val handle: T
) : EntityController<T> {
override fun addEntityGoal(priority: Int, goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.addGoal(
priority,
goal.getGoalFactory()?.create(goal, nms) ?: return this
)
return this
}
override fun removeEntityGoal(goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.goalSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.goalSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearEntityGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.availableGoals.clear()
return this
}
override fun addTargetGoal(priority: Int, goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.addGoal(
priority, goal.getGoalFactory()?.create(goal, nms) ?: return this
)
nms.targetSelector
return this
}
override fun removeTargetGoal(goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.targetSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.targetSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearTargetGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.availableGoals.clear()
return this
}
private fun getNms(): PathfinderMob? {
return handle.toPathfinderMob()
}
override fun getEntity(): T {
return handle
}
}

View File

@@ -0,0 +1,185 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5.item
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import net.minecraft.core.component.DataComponents
import net.minecraft.world.item.component.TooltipDisplay
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
open class NewerEcoFastItemStack(
bukkit: ItemStack,
) : NewEcoFastItemStack(bukkit) {
override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ENCHANTMENTS, true)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ATTRIBUTE_MODIFIERS, true)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.UNBREAKABLE, true)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_BREAK, true)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_PLACE_ON, true)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
TooltipDisplay(true, tooltip.hiddenComponents)
}
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.DYED_COLOR, true)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.TRIM, true)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.STORED_ENCHANTMENTS, true)
}
}
}
}
apply()
}
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ENCHANTMENTS, false)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ATTRIBUTE_MODIFIERS, false)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.UNBREAKABLE, false)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_BREAK, false)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_PLACE_ON, false)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
TooltipDisplay(false, tooltip.hiddenComponents)
}
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.DYED_COLOR, false)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.TRIM, false)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.STORED_ENCHANTMENTS, false)
}
}
}
}
apply()
}
override fun hasItemFlag(flag: ItemFlag): Boolean {
return when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.ENCHANTMENTS)
}
ItemFlag.HIDE_ATTRIBUTES -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.ATTRIBUTE_MODIFIERS)
}
ItemFlag.HIDE_UNBREAKABLE -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.UNBREAKABLE)
}
ItemFlag.HIDE_DESTROYS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.CAN_BREAK)
}
ItemFlag.HIDE_PLACED_ON -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.CAN_PLACE_ON)
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
tooltip.hideTooltip
}
ItemFlag.HIDE_DYE -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.DYED_COLOR)
}
ItemFlag.HIDE_ARMOR_TRIM -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.TRIM)
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.STORED_ENCHANTMENTS)
}
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket
import net.minecraft.world.item.trading.MerchantOffers
object NewItemsPacketOpenWindowMerchant : PacketListener {
private val field = ClientboundMerchantOffersPacket::class.java
.declaredFields
.first { it.type == MerchantOffers::class.java }
.apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundMerchantOffersPacket ?: return
val offers = MerchantOffers()
for (offer in packet.offers) {
val new = offer.copy()
Display.display(new.baseCostA.itemStack.asBukkitStack(), event.player)
if (new.costB.isPresent) {
Display.display(new.costB.get().itemStack.asBukkitStack(), event.player)
}
Display.display(new.result.asBukkitStack(), event.player)
offers += new
}
field.set(packet, offers)
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
object NewItemsPacketSetCreativeSlot : PacketListener {
override fun onReceive(event: PacketEvent) {
val packet = event.packet.handle as? ServerboundSetCreativeModeSlotPacket ?: return
Display.revert(packet.itemStack.asBukkitStack())
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -0,0 +1,52 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_5.packet
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.asNMSStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
class NewItemsPacketWindowItems(
plugin: EcoPlugin
) : PacketWindowItems(plugin) {
private val lastKnownWindowIDs = ConcurrentHashMap<UUID, Int>()
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundContainerSetContentPacket ?: return
val player = event.player
Display.display(packet.carriedItem.asBukkitStack(), player)
val windowId = packet.containerId
val lastKnownID = lastKnownWindowIDs[player.uniqueId]
lastKnownWindowIDs[player.uniqueId] = windowId
// If there is any change in window ID at any point,
// Remove the last display frame to prevent any potential conflicts.
// If the window ID is not zero (not a player inventory), then remove too,
// as GUIs are not player inventories.
if (lastKnownID != windowId || windowId != 0) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}
val itemStacks = packet.items.map { it.asBukkitStack() }
val newItems = modifyWindowItems(itemStacks.toMutableList(), windowId, player)
val newPacket = ClientboundContainerSetContentPacket(
packet.containerId,
packet.stateId,
newItems.map { it.asNMSStack() },
packet.carriedItem,
)
event.packet.handle = newPacket
}
}

View File

@@ -0,0 +1,52 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("io.papermc.paperweight.userdev")
}
group = "com.willfp"
version = rootProject.version
dependencies {
implementation(project(":eco-core:core-nms:modern"))
implementation(project(":eco-core:core-nms:common"))
paperweight.paperDevBundle("1.21.6-R0.1-SNAPSHOT")
implementation("net.kyori:adventure-text-minimessage:4.11.0") {
version {
strictly("4.11.0")
}
exclude(group = "net.kyori", module = "adventure-api")
}
}
tasks {
build {
dependsOn(reobfJar)
}
reobfJar {
mustRunAfter(shadowJar)
}
shadowJar {
relocate(
"com.willfp.eco.internal.spigot.proxy.common",
"com.willfp.eco.internal.spigot.proxy.v1_21_6.common"
)
relocate(
"net.kyori.adventure.text.minimessage",
"com.willfp.eco.internal.spigot.proxy.v1_21_6.minimessage"
)
}
compileJava {
options.release.set(21)
}
compileKotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.command.PluginCommandBase
import com.willfp.eco.internal.spigot.proxy.BukkitCommandsProxy
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.SimpleCommandMap
import org.bukkit.craftbukkit.CraftServer
import java.lang.reflect.Field
class BukkitCommands : BukkitCommandsProxy {
private val knownCommandsField: Field by lazy {
SimpleCommandMap::class.java.getDeclaredField("knownCommands")
.apply {
isAccessible = true
}
}
@Suppress("UNCHECKED_CAST")
private val knownCommands: MutableMap<String, Command>
get() = knownCommandsField.get(getCommandMap()) as MutableMap<String, Command>
override fun getCommandMap(): SimpleCommandMap {
return (Bukkit.getServer() as CraftServer).commandMap
}
override fun syncCommands() {
(Bukkit.getServer() as CraftServer).syncCommands()
}
override fun unregisterCommand(command: PluginCommandBase) {
knownCommands.remove(command.name)
knownCommands.remove("${command.plugin.name.lowercase()}:${command.name}")
}
}

View File

@@ -0,0 +1,172 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import ca.spottedleaf.dataconverter.minecraft.MCDataConverter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import com.willfp.eco.internal.spigot.proxy.common.packet.PacketInjectorListener
import com.willfp.eco.internal.spigot.proxy.common.toResourceLocation
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer
import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.network.chat.ComponentSerialization
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.entity.CraftEntity
import org.bukkit.craftbukkit.entity.CraftMob
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.inventory.CraftMetaArmor
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.craftbukkit.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy {
override fun init(plugin: EcoPlugin) {
CommonsProvider.setIfNeeded(CommonsProviderImpl)
plugin.onEnable {
plugin.eventManager.registerListener(PacketInjectorListener)
}
}
object CommonsProviderImpl : CommonsProvider {
private val cisHandle: Field = CraftItemStack::class.java.getDeclaredField("handle").apply {
isAccessible = true
}
private val pdcRegsitry = CraftMetaArmor::class.java
.superclass // Access CraftMetaItem
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = 8
override fun toPathfinderMob(mob: Mob): PathfinderMob? {
val craft = mob as? CraftMob ?: return null
return craft.handle as? PathfinderMob
}
override fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation =
CraftNamespacedKey.toMinecraft(namespacedKey)
override fun asNMSStack(itemStack: ItemStack): net.minecraft.world.item.ItemStack {
return if (itemStack !is CraftItemStack) {
CraftItemStack.asNMSCopy(itemStack)
} else {
cisHandle[itemStack] as net.minecraft.world.item.ItemStack? ?: CraftItemStack.asNMSCopy(itemStack)
}
}
override fun asBukkitStack(itemStack: net.minecraft.world.item.ItemStack): ItemStack {
return CraftItemStack.asCraftMirror(itemStack)
}
override fun mergeIfNeeded(itemStack: ItemStack, nmsStack: net.minecraft.world.item.ItemStack) {
if (itemStack !is CraftItemStack) {
itemStack.itemMeta = CraftItemStack.asCraftMirror(nmsStack).itemMeta
}
}
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.keySet()
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").get().toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.keySet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.remove(DataComponents.CUSTOM_DATA)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
override fun materialToItem(material: Material): Item =
BuiltInRegistries.ITEM.getOptional(material.key.toResourceLocation())
.orElseThrow { IllegalArgumentException("Material is not item!") }
override fun itemToMaterial(item: Item) =
Material.getMaterial(BuiltInRegistries.ITEM.getKey(item).path.uppercase())
?: throw IllegalArgumentException("Invalid material!")
override fun toNMS(player: Player): ServerPlayer {
return (player as CraftPlayer).handle
}
override fun toNMS(component: Component): net.minecraft.network.chat.Component {
// TODO: Don't have hard dependency on paper
return PaperAdventure.asVanilla(component)
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.packet.Packet
import com.willfp.eco.core.packet.sendPacket
import com.willfp.eco.internal.spigot.proxy.DisplayNameProxy
import com.willfp.eco.internal.spigot.proxy.common.toNMS
import net.kyori.adventure.text.Component
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.entity.Entity
import org.bukkit.craftbukkit.entity.CraftLivingEntity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import java.util.Optional
@Suppress("UNCHECKED_CAST")
class DisplayName : DisplayNameProxy {
private val displayNameAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[2]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Optional<net.minecraft.network.chat.Component>>
private val customNameVisibleAccessor = Entity::class.java
.declaredFields
.filter { it.type == EntityDataAccessor::class.java }
.toList()[3]
.apply { isAccessible = true }
.get(null) as EntityDataAccessor<Boolean>
override fun setClientsideDisplayName(
entity: LivingEntity,
player: Player,
displayName: Component,
visible: Boolean
) {
if (entity !is CraftLivingEntity) {
return
}
val nmsComponent = displayName.toNMS()
val nmsEntity = entity.handle
val packet = ClientboundSetEntityDataPacket(
nmsEntity.id,
listOf(
SynchedEntityData.DataValue.create(displayNameAccessor, Optional.of(nmsComponent)),
SynchedEntityData.DataValue.create(customNameVisibleAccessor, visible)
)
)
player.sendPacket(Packet(packet))
}
}

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.internal.entities.EcoDummyEntity
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import org.bukkit.Location
import org.bukkit.craftbukkit.CraftWorld
import org.bukkit.entity.Entity
import org.bukkit.entity.Zombie
class DummyEntityFactory : DummyEntityFactoryProxy {
override fun createDummyEntity(location: Location): Entity {
val world = location.world as CraftWorld
return EcoDummyEntity(world.createEntity(location, Zombie::class.java))
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.v1_21_6.entity.EcoEntityController
import org.bukkit.entity.Mob
class EntityControllerFactory : EntityControllerFactoryProxy {
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
return EcoEntityController(entity)
}
}

View File

@@ -0,0 +1,91 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.Material
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
import java.lang.reflect.Field
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
private val registry: CraftPersistentDataTypeRegistry
init {
/*
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
And getting it would mean more janky reflection
*/
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
val pdc = item.itemMeta!!.persistentDataContainer
// Cross-version compatibility:
val registryField: Field = try {
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
} catch (e: NoSuchFieldException) {
CraftPersistentDataContainer::class.java.superclass.getDeclaredField("registry")
}
this.registry = registryField
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
}
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance ${pdc::class.java.name} is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
private val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] =
registry.wrap(dataType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract<T, Tag>(dataType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import com.willfp.eco.internal.spigot.proxy.v1_21_6.item.NewerEcoFastItemStack
import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy {
override fun create(itemStack: ItemStack): FastItemStack {
return NewerEcoFastItemStack(itemStack)
}
}

View File

@@ -0,0 +1,33 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.minimessage.MiniMessage
class MiniMessageTranslator : MiniMessageTranslatorProxy {
override fun format(message: String): String {
var mut = message
val startsWithPrefix = mut.startsWith(Display.PREFIX)
if (startsWithPrefix) {
mut = mut.substring(2)
}
mut = mut.replace('§', '&')
val miniMessage = runCatching {
MiniMessage.miniMessage().deserialize(
mut
).toLegacy()
}.getOrNull() ?: mut
mut = if (startsWithPrefix) {
Display.PREFIX + miniMessage
} else {
miniMessage
}
return mut
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.PacketHandlerProxy
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketHeldItemSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketSetSlot
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.clearFrames
import com.willfp.eco.internal.spigot.proxy.v1_21_6.packet.NewItemsPacketOpenWindowMerchant
import com.willfp.eco.internal.spigot.proxy.v1_21_6.packet.NewItemsPacketSetCreativeSlot
import com.willfp.eco.internal.spigot.proxy.v1_21_6.packet.NewItemsPacketWindowItems
import net.minecraft.network.protocol.Packet
import org.bukkit.craftbukkit.entity.CraftPlayer
import org.bukkit.entity.Player
class PacketHandler : PacketHandlerProxy {
override fun sendPacket(player: Player, packet: com.willfp.eco.core.packet.Packet) {
if (player !is CraftPlayer) {
return
}
val handle = packet.handle
if (handle !is Packet<*>) {
return
}
player.handle.connection.send(handle)
}
override fun clearDisplayFrames() {
clearFrames()
}
override fun getPacketListeners(plugin: EcoPlugin): List<PacketListener> {
// No PacketAutoRecipe for 1.21.3+ because recipes have been changed internally
return listOf(
PacketHeldItemSlot,
NewItemsPacketOpenWindowMerchant,
NewItemsPacketSetCreativeSlot,
PacketSetSlot,
NewItemsPacketWindowItems(plugin)
)
}
}

View File

@@ -0,0 +1,95 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.mojang.serialization.Dynamic
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.SnbtPrinterTagVisitor
import net.minecraft.nbt.TagParser
import net.minecraft.server.MinecraftServer
import net.minecraft.util.datafix.fixes.References
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
import org.bukkit.craftbukkit.inventory.CraftItemStack
import org.bukkit.craftbukkit.util.CraftMagicNumbers
import org.bukkit.inventory.ItemStack
private val registryAccess = (Bukkit.getServer() as CraftServer).server.registryAccess()
class SNBTConverter : SNBTConverterProxy {
private fun parseItemSNBT(snbt: String): CompoundTag? {
val nbt = runCatching { TagParser.parseCompoundFully(snbt) }.getOrNull() ?: return null
val dataVersion = if (nbt.contains("DataVersion")) {
nbt.getInt("DataVersion").get()
} else null
// If the data version is the same as the server's data version, we don't need to fix it
if (dataVersion == CraftMagicNumbers.INSTANCE.dataVersion) {
return nbt
}
return MinecraftServer.getServer().fixerUpper.update(
References.ITEM_STACK,
Dynamic(NbtOps.INSTANCE, nbt),
dataVersion ?: 3700, // 3700 is the 1.20.4 data version
CraftMagicNumbers.INSTANCE.dataVersion
).value as CompoundTag
}
private fun nmsToNbt(nms: net.minecraft.world.item.ItemStack): CompoundTag {
return net.minecraft.world.item.ItemStack.CODEC
.encodeStart(registryAccess.createSerializationContext(NbtOps.INSTANCE), nms)
.result()
.get() as CompoundTag
}
private fun nbtToNms(tag: CompoundTag): net.minecraft.world.item.ItemStack? {
return net.minecraft.world.item.ItemStack.CODEC
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), tag)
.result()
.orElse(null)
}
override fun fromSNBT(snbt: String): ItemStack? {
val tag = parseItemSNBT(snbt) ?: return null
val nms = nbtToNms(tag) ?: return null
return CraftItemStack.asBukkitCopy(nms)
}
override fun toSNBT(itemStack: ItemStack): String {
val nms = CraftItemStack.asNMSCopy(itemStack)
val tag = nmsToNbt(nms)
tag.putInt("DataVersion", CraftMagicNumbers.INSTANCE.dataVersion)
return SnbtPrinterTagVisitor().visit(tag)
}
override fun makeSNBTTestable(snbt: String): TestableItem {
val tag = parseItemSNBT(snbt) ?: return EmptyTestableItem()
val nms = nbtToNms(tag)
tag.remove("Count")
return SNBTTestableItem(CraftItemStack.asBukkitCopy(nms), tag)
}
inner class SNBTTestableItem(
private val item: ItemStack,
private val tag: CompoundTag
) : TestableItem {
override fun matches(itemStack: ItemStack?): Boolean {
if (itemStack == null) {
return false
}
val nms = CraftItemStack.asNMSCopy(itemStack)
val nmsTag = nmsToNbt(nms)
nmsTag.remove("Count")
return tag.copy().merge(nmsTag) == nmsTag && itemStack.type == item.type
}
override fun getItem(): ItemStack = item
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.internal.spigot.proxy.SkullProxy
import com.willfp.eco.internal.spigot.proxy.common.modern.texture
import org.bukkit.inventory.meta.SkullMeta
class Skull : SkullProxy {
override fun setSkullTexture(
meta: SkullMeta,
base64: String
) {
meta.texture = base64
}
override fun getSkullTexture(
meta: SkullMeta
): String? = meta.texture
}

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6
import com.willfp.eco.internal.spigot.proxy.TPSProxy
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.CraftServer
class TPS : TPSProxy {
override fun getTPS(): Double {
return (Bukkit.getServer() as CraftServer).handle.server.tps1.average
}
}

View File

@@ -0,0 +1,95 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6.entity
import com.willfp.eco.core.entities.ai.CustomGoal
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.internal.spigot.proxy.common.ai.CustomGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.ai.getGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.toPathfinderMob
import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.goal.Goal
import org.bukkit.entity.Mob
class EcoEntityController<T : Mob>(
private val handle: T
) : EntityController<T> {
override fun addEntityGoal(priority: Int, goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.addGoal(
priority,
goal.getGoalFactory()?.create(goal, nms) ?: return this
)
return this
}
override fun removeEntityGoal(goal: EntityGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.goalSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.goalSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearEntityGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.goalSelector.availableGoals.clear()
return this
}
override fun addTargetGoal(priority: Int, goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.addGoal(
priority, goal.getGoalFactory()?.create(goal, nms) ?: return this
)
nms.targetSelector
return this
}
override fun removeTargetGoal(goal: TargetGoal<in T>): EntityController<T> {
val nms = getNms() ?: return this
val predicate: (Goal) -> Boolean = if (goal is CustomGoal<*>) {
{ CustomGoalFactory.isGoalOfType(it, goal) }
} else {
{ goal.getGoalFactory()?.isGoalOfType(it) == true }
}
for (wrapped in nms.targetSelector.availableGoals.toSet()) {
if (predicate(wrapped.goal)) {
nms.targetSelector.removeGoal(wrapped.goal)
}
}
return this
}
override fun clearTargetGoals(): EntityController<T> {
val nms = getNms() ?: return this
nms.targetSelector.availableGoals.clear()
return this
}
private fun getNms(): PathfinderMob? {
return handle.toPathfinderMob()
}
override fun getEntity(): T {
return handle
}
}

View File

@@ -0,0 +1,185 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6.item
import com.willfp.eco.internal.spigot.proxy.common.modern.NewEcoFastItemStack
import net.minecraft.core.component.DataComponents
import net.minecraft.world.item.component.TooltipDisplay
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
open class NewerEcoFastItemStack(
bukkit: ItemStack,
) : NewEcoFastItemStack(bukkit) {
override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ENCHANTMENTS, true)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ATTRIBUTE_MODIFIERS, true)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.UNBREAKABLE, true)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_BREAK, true)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_PLACE_ON, true)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
TooltipDisplay(true, tooltip.hiddenComponents)
}
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.DYED_COLOR, true)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.TRIM, true)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.STORED_ENCHANTMENTS, true)
}
}
}
}
apply()
}
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ENCHANTMENTS, false)
}
}
ItemFlag.HIDE_ATTRIBUTES -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.ATTRIBUTE_MODIFIERS, false)
}
}
ItemFlag.HIDE_UNBREAKABLE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.UNBREAKABLE, false)
}
}
ItemFlag.HIDE_DESTROYS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_BREAK, false)
}
}
ItemFlag.HIDE_PLACED_ON -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.CAN_PLACE_ON, false)
}
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
TooltipDisplay(false, tooltip.hiddenComponents)
}
}
ItemFlag.HIDE_DYE -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.DYED_COLOR, false)
}
}
ItemFlag.HIDE_ARMOR_TRIM -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.TRIM, false)
}
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
handle.modifyComponent(DataComponents.TOOLTIP_DISPLAY) { tooltip ->
tooltip.withHidden(DataComponents.STORED_ENCHANTMENTS, false)
}
}
}
}
apply()
}
override fun hasItemFlag(flag: ItemFlag): Boolean {
return when (flag) {
ItemFlag.HIDE_ENCHANTS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.ENCHANTMENTS)
}
ItemFlag.HIDE_ATTRIBUTES -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.ATTRIBUTE_MODIFIERS)
}
ItemFlag.HIDE_UNBREAKABLE -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.UNBREAKABLE)
}
ItemFlag.HIDE_DESTROYS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.CAN_BREAK)
}
ItemFlag.HIDE_PLACED_ON -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.CAN_PLACE_ON)
}
ItemFlag.HIDE_ADDITIONAL_TOOLTIP -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
tooltip.hideTooltip
}
ItemFlag.HIDE_DYE -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.DYED_COLOR)
}
ItemFlag.HIDE_ARMOR_TRIM -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.TRIM)
}
ItemFlag.HIDE_STORED_ENCHANTS -> {
val tooltip = handle.get(DataComponents.TOOLTIP_DISPLAY) ?: return false
!tooltip.shows(DataComponents.STORED_ENCHANTMENTS)
}
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket
import net.minecraft.world.item.trading.MerchantOffers
object NewItemsPacketOpenWindowMerchant : PacketListener {
private val field = ClientboundMerchantOffersPacket::class.java
.declaredFields
.first { it.type == MerchantOffers::class.java }
.apply { isAccessible = true }
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundMerchantOffersPacket ?: return
val offers = MerchantOffers()
for (offer in packet.offers) {
val new = offer.copy()
Display.display(new.baseCostA.itemStack.asBukkitStack(), event.player)
if (new.costB.isPresent) {
Display.display(new.costB.get().itemStack.asBukkitStack(), event.player)
}
Display.display(new.result.asBukkitStack(), event.player)
offers += new
}
field.set(packet, offers)
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6.packet
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.core.packet.PacketListener
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
object NewItemsPacketSetCreativeSlot : PacketListener {
override fun onReceive(event: PacketEvent) {
val packet = event.packet.handle as? ServerboundSetCreativeModeSlotPacket ?: return
Display.revert(packet.itemStack.asBukkitStack())
event.player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -0,0 +1,52 @@
package com.willfp.eco.internal.spigot.proxy.v1_21_6.packet
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.packet.PacketEvent
import com.willfp.eco.internal.spigot.proxy.common.asBukkitStack
import com.willfp.eco.internal.spigot.proxy.common.asNMSStack
import com.willfp.eco.internal.spigot.proxy.common.packet.display.PacketWindowItems
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.proxy.common.packet.display.frame.lastDisplayFrame
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
class NewItemsPacketWindowItems(
plugin: EcoPlugin
) : PacketWindowItems(plugin) {
private val lastKnownWindowIDs = ConcurrentHashMap<UUID, Int>()
override fun onSend(event: PacketEvent) {
val packet = event.packet.handle as? ClientboundContainerSetContentPacket ?: return
val player = event.player
Display.display(packet.carriedItem.asBukkitStack(), player)
val windowId = packet.containerId
val lastKnownID = lastKnownWindowIDs[player.uniqueId]
lastKnownWindowIDs[player.uniqueId] = windowId
// If there is any change in window ID at any point,
// Remove the last display frame to prevent any potential conflicts.
// If the window ID is not zero (not a player inventory), then remove too,
// as GUIs are not player inventories.
if (lastKnownID != windowId || windowId != 0) {
player.lastDisplayFrame = DisplayFrame.EMPTY
}
val itemStacks = packet.items.map { it.asBukkitStack() }
val newItems = modifyWindowItems(itemStacks.toMutableList(), windowId, player)
val newPacket = ClientboundContainerSetContentPacket(
packet.containerId,
packet.stateId,
newItems.map { it.asNMSStack() },
packet.carriedItem,
)
event.packet.handle = newPacket
}
}

View File

@@ -57,8 +57,8 @@ dependencies {
exclude(group = "*", module = "*")
}
compileOnly("com.iridium:IridiumSkyblock:4.0.8")
compileOnly("net.william278.huskclaims:huskclaims-bukkit:1.0.1")
compileOnly("net.william278:husktowns:2.6.1")
compileOnly("net.william278.huskclaims:huskclaims-bukkit:1.5")
compileOnly("net.william278.husktowns:husktowns-bukkit:3.0.8")
compileOnly("com.github.jojodmo:ItemBridge:b0054538c1")
compileOnly("de.oliver:FancyHolograms:2.4.0")

View File

@@ -18,9 +18,12 @@ import com.willfp.eco.core.placeholder.context.PlaceholderContext
import com.willfp.eco.internal.EcoPropsParser
import com.willfp.eco.internal.command.EcoPluginCommand
import com.willfp.eco.internal.command.EcoSubcommand
import com.willfp.eco.internal.config.*
import com.willfp.eco.internal.config.EcoConfigSection
import com.willfp.eco.internal.config.EcoLoadableConfig
import com.willfp.eco.internal.config.EcoUpdatableConfig
import com.willfp.eco.internal.config.handler.ReflectiveConfigHandler
import com.willfp.eco.internal.config.handler.SimpleConfigHandler
import com.willfp.eco.internal.config.toMap
import com.willfp.eco.internal.drops.EcoDropQueue
import com.willfp.eco.internal.drops.EcoFastCollatedDropQueue
import com.willfp.eco.internal.events.EcoEventManager

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.internal.spigot.integrations.antigrief
import com.craftaro.skyblock.SkyBlock
import com.songoda.skyblock.SkyBlock
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
import org.bukkit.Location
import org.bukkit.block.Block

View File

@@ -1,39 +1,34 @@
package com.willfp.eco.internal.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
import net.crashcraft.crashclaim.CrashClaim
import net.crashcraft.crashclaim.permissions.PermissionRoute
import net.william278.huskclaims.api.HuskClaimsAPI
import net.william278.huskclaims.api.BukkitHuskClaimsAPI
import net.william278.huskclaims.libraries.cloplib.operation.Operation
import net.william278.huskclaims.libraries.cloplib.operation.OperationPosition
import net.william278.huskclaims.libraries.cloplib.operation.OperationType
import net.william278.huskclaims.position.Position
import net.william278.huskclaims.position.World
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Monster
import org.bukkit.entity.Player
import kotlin.jvm.optionals.getOrElse
class AntigriefHuskClaims : AntigriefIntegration {
override fun canBreakBlock(
player: Player,
block: Block
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val api = BukkitHuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
OperationType.BLOCK_BREAK,
Position.at(
block.x.toDouble(),
block.y.toDouble(),
block.z.toDouble(),
api.getWorld(block.location.world.name)
block.location.x,
block.location.y,
block.location.z,
api.getWorld(block.world)
),
true
)
@@ -44,9 +39,9 @@ class AntigriefHuskClaims : AntigriefIntegration {
player: Player,
location: Location
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val api = BukkitHuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
@@ -56,7 +51,7 @@ class AntigriefHuskClaims : AntigriefIntegration {
location.x,
location.y,
location.z,
api.getWorld(location.world.name)
api.getWorld(location.world)
),
true
)
@@ -67,19 +62,19 @@ class AntigriefHuskClaims : AntigriefIntegration {
player: Player,
block: Block
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val api = BukkitHuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
OperationType.BLOCK_PLACE,
Position.at(
block.x.toDouble(),
block.y.toDouble(),
block.z.toDouble(),
api.getWorld(block.location.world.name)
block.location.x,
block.location.y,
block.location.z,
api.getWorld(block.world)
),
true
)
@@ -90,23 +85,23 @@ class AntigriefHuskClaims : AntigriefIntegration {
player: Player,
victim: LivingEntity
): Boolean {
val api = HuskClaimsAPI.getInstance() ?: return true
val api = BukkitHuskClaimsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player.uniqueId) ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
when (victim) {
when(victim) {
is Monster -> OperationType.PLAYER_DAMAGE_MONSTER
is Player -> OperationType.PLAYER_DAMAGE_PLAYER
else -> OperationType.PLAYER_DAMAGE_ENTITY
},
Position.at(
victim.x,
victim.y,
victim.z,
api.getWorld(victim.location.world.name)
player.location.x,
player.location.y,
player.location.z,
api.getWorld(player.world)
),
true
)

View File

@@ -1,9 +1,10 @@
package com.willfp.eco.internal.spigot.integrations.antigrief
import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
import net.william278.husktowns.api.HuskTownsAPI
import net.william278.husktowns.api.BukkitHuskTownsAPI
import net.william278.husktowns.claim.Position
import net.william278.husktowns.listener.Operation
import net.william278.husktowns.libraries.cloplib.operation.Operation
import net.william278.husktowns.libraries.cloplib.operation.OperationType
import org.bukkit.Location
import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity
@@ -15,14 +16,14 @@ class AntigriefHuskTowns : AntigriefIntegration {
player: Player,
block: Block
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val api = BukkitHuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.BLOCK_BREAK,
OperationType.BLOCK_BREAK,
Position.at(
block.location.x,
block.location.y,
@@ -38,14 +39,14 @@ class AntigriefHuskTowns : AntigriefIntegration {
player: Player,
location: Location
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val api = BukkitHuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.EXPLOSION_DAMAGE_ENTITY,
OperationType.EXPLOSION_DAMAGE_ENTITY,
Position.at(
location.x,
location.y,
@@ -61,14 +62,14 @@ class AntigriefHuskTowns : AntigriefIntegration {
player: Player,
block: Block
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val api = BukkitHuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
return api.isOperationAllowed(
Operation.of(
user,
Operation.Type.BLOCK_PLACE,
OperationType.BLOCK_PLACE,
Position.at(
block.location.x,
block.location.y,
@@ -84,7 +85,7 @@ class AntigriefHuskTowns : AntigriefIntegration {
player: Player,
victim: LivingEntity
): Boolean {
val api = HuskTownsAPI.getInstance() ?: return true
val api = BukkitHuskTownsAPI.getInstance() ?: return true
val user = api.getOnlineUser(player) ?: return true
@@ -92,9 +93,9 @@ class AntigriefHuskTowns : AntigriefIntegration {
Operation.of(
user,
when(victim) {
is Monster -> Operation.Type.PLAYER_DAMAGE_MONSTER
is Player -> Operation.Type.PLAYER_DAMAGE_PLAYER
else -> Operation.Type.PLACE_HANGING_ENTITY
is Monster -> OperationType.PLAYER_DAMAGE_MONSTER
is Player -> OperationType.PLAYER_DAMAGE_PLAYER
else -> OperationType.PLACE_HANGING_ENTITY
},
Position.at(
player.location.x,

View File

@@ -9,7 +9,6 @@ import java.io.DataOutputStream
import java.io.File
import java.io.InputStreamReader
import java.net.URI
import java.net.URL
import java.nio.charset.StandardCharsets
import java.util.UUID
import java.util.concurrent.Executors

View File

@@ -1,13 +1,13 @@
package com.willfp.eco.internal.spigot.integrations.customitems
import com.denizenscript.denizen.objects.ItemTag
import com.denizenscript.denizen.scripts.containers.core.ItemScriptHelper
import com.willfp.eco.core.integrations.customitems.CustomItemsIntegration
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.TestableItem
import com.willfp.eco.core.items.provider.ItemProvider
import com.willfp.eco.util.NamespacedKeyUtils
import com.denizenscript.denizen.objects.ItemTag
import com.denizenscript.denizen.scripts.containers.core.ItemScriptHelper
import com.willfp.eco.core.items.Items
import org.bukkit.event.Listener
class CustomItemsDenizen : CustomItemsIntegration, Listener {

View File

@@ -7,7 +7,7 @@ import com.willfp.eco.core.price.PriceFactory
import com.willfp.eco.util.toSingletonList
import me.qKing12.RoyaleEconomy.MultiCurrency.Currency
import org.bukkit.entity.Player
import java.util.*
import java.util.UUID
class PriceFactoryRoyaleEconomy(private val currency: Currency) : PriceFactory {

View File

@@ -1,3 +1,3 @@
version = 6.75.1
version = 6.76.1
kotlin.daemon.jvmargs=-Xmx2g -XX:+UseG1GC -XX:MaxMetaspaceSize=512m
org.gradle.parallel=true

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,6 @@
pluginManagement {
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
gradlePluginPortal()
}
}
@@ -28,7 +29,9 @@ include(":eco-core:core-nms:v1_20_R3")
include(":eco-core:core-nms:v1_21")
include(":eco-core:core-nms:v1_21_3")
include(":eco-core:core-nms:v1_21_4")
include(":eco-core:core-nms:v1_21_5")
include(":eco-core:core-nms:v1_21_6")
include(":eco-core:core-proxy")
include(":eco-core:core-plugin")
include(":eco-core:core-backend")
include(":eco-core:core-backend-modern")
include(":eco-core:core-backend-modern")