Update KSpigot to 1.18.1

This commit is contained in:
Jakob K
2021-12-12 03:06:10 +01:00
parent c23b41e086
commit cc4d180902
10 changed files with 76 additions and 84 deletions

View File

@@ -5,7 +5,7 @@ import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.builder.RequiredArgumentBuilder import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.mojang.brigadier.context.CommandContext import com.mojang.brigadier.context.CommandContext
import net.axay.kspigot.commands.internal.ArgumentTypeUtils import net.axay.kspigot.commands.internal.ArgumentTypeUtils
import net.axay.kspigot.commands.internal.ServerCommandSource import net.minecraft.commands.CommandSourceStack
/** /**
* Adds an argument. * Adds an argument.
@@ -13,12 +13,12 @@ import net.axay.kspigot.commands.internal.ServerCommandSource
* @param name the name of the argument * @param name the name of the argument
* @param type the type of the argument - e.g. IntegerArgumentType.integer() or StringArgumentType.string() * @param type the type of the argument - e.g. IntegerArgumentType.integer() or StringArgumentType.string()
*/ */
inline fun <T> ArgumentBuilder<ServerCommandSource, *>.argument( inline fun <T> ArgumentBuilder<CommandSourceStack, *>.argument(
name: String, name: String,
type: ArgumentType<T>, type: ArgumentType<T>,
builder: RequiredArgumentBuilder<ServerCommandSource, T>.() -> Unit = {} builder: RequiredArgumentBuilder<CommandSourceStack, T>.() -> Unit = {}
): RequiredArgumentBuilder<ServerCommandSource, T> = ): RequiredArgumentBuilder<CommandSourceStack, T> =
RequiredArgumentBuilder.argument<ServerCommandSource, T>(name, type).apply(builder).also { then(it) } RequiredArgumentBuilder.argument<CommandSourceStack, T>(name, type).apply(builder).also { then(it) }
/** /**
* Adds an argument. The argument type will be resolved via the reified * Adds an argument. The argument type will be resolved via the reified
@@ -27,14 +27,14 @@ inline fun <T> ArgumentBuilder<ServerCommandSource, *>.argument(
* @param name the name of the argument * @param name the name of the argument
*/ */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
inline fun <reified T> ArgumentBuilder<ServerCommandSource, *>.argument( inline fun <reified T> ArgumentBuilder<CommandSourceStack, *>.argument(
name: String, name: String,
builder: RequiredArgumentBuilder<ServerCommandSource, T>.() -> Unit = {} builder: RequiredArgumentBuilder<CommandSourceStack, T>.() -> Unit = {}
): RequiredArgumentBuilder<ServerCommandSource, T> = ): RequiredArgumentBuilder<CommandSourceStack, T> =
RequiredArgumentBuilder.argument<ServerCommandSource, T>(name, ArgumentTypeUtils.fromReifiedType<T>()).apply(builder).also { then(it) } RequiredArgumentBuilder.argument<CommandSourceStack, T>(name, ArgumentTypeUtils.fromReifiedType<T>()).apply(builder).also { then(it) }
/** /**
* Get the value of this argument. * Get the value of this argument.
*/ */
inline fun <reified T> CommandContext<ServerCommandSource>.getArgument(name: String): T = inline fun <reified T> CommandContext<CommandSourceStack>.getArgument(name: String): T =
getArgument(name, T::class.java) getArgument(name, T::class.java)

View File

@@ -1,19 +1,13 @@
package net.axay.kspigot.commands package net.axay.kspigot.commands
import com.mojang.brigadier.context.CommandContext import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType import net.minecraft.commands.CommandSourceStack
import net.axay.kspigot.commands.internal.ServerCommandSource
import net.minecraft.network.chat.ChatMessage
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Server import org.bukkit.Server
import org.bukkit.World import org.bukkit.World
import org.bukkit.entity.Player import org.bukkit.entity.Player
class CommandContext(val nmsContext: CommandContext<ServerCommandSource>) { class CommandContext(val nmsContext: CommandContext<CommandSourceStack>) {
companion object {
private val REQUIRES_PLAYER_EXCEPTION = SimpleCommandExceptionType(ChatMessage("permissions.requires.player"))
}
/** /**
* Get the value of the given argument. * Get the value of the given argument.
*/ */
@@ -23,13 +17,13 @@ class CommandContext(val nmsContext: CommandContext<ServerCommandSource>) {
/** /**
* The source / sender which executed this command. * The source / sender which executed this command.
*/ */
val sender get() = nmsContext.source.bukkitSender val sender: CommandSourceStack get() = nmsContext.source
/** /**
* Validates that this command was executes by a player (sends an error message to the sender if this is not the case) * Validates that this command was executes by a player (sends an error message to the sender if this is not the case)
* and returns the [Player]. * and returns the [Player].
*/ */
val player get() = nmsContext.source.bukkitSender as? Player ?: throw REQUIRES_PLAYER_EXCEPTION.create() val player: Player get() = nmsContext.source.bukkitSender as? Player ?: throw CommandSourceStack.ERROR_NOT_PLAYER.create()
/** /**
* The world where the source of this command currently is in. * The world where the source of this command currently is in.
@@ -38,17 +32,17 @@ class CommandContext(val nmsContext: CommandContext<ServerCommandSource>) {
* these cases are rare (e.g. command called by a datapack function), therefore * these cases are rare (e.g. command called by a datapack function), therefore
* this property is not nullable for convenience * this property is not nullable for convenience
*/ */
val world get() = nmsContext.source.world.world as World val world: World get() = nmsContext.source.bukkitWorld!!
/** /**
* The position of the source of this command. * The position of the source of this command.
*/ */
val position get() = with(nmsContext.source.position) { val position: Location get() = with(nmsContext.source.position) {
Location(nmsContext.source.world.world as? World?, x, y, z) Location(nmsContext.source.bukkitWorld, x, y, z)
} }
/** /**
* The current server instance. * The current server instance.
*/ */
val server get() = nmsContext.source.server.server as Server val server: Server get() = nmsContext.source.server.server as Server
} }

View File

@@ -3,7 +3,7 @@ package net.axay.kspigot.commands
import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.builder.LiteralArgumentBuilder
import net.axay.kspigot.commands.internal.BrigardierSupport import net.axay.kspigot.commands.internal.BrigardierSupport
import net.axay.kspigot.commands.internal.ServerCommandSource import net.minecraft.commands.CommandSourceStack
/** /**
* Creates a new command. * Creates a new command.
@@ -14,9 +14,9 @@ import net.axay.kspigot.commands.internal.ServerCommandSource
inline fun command( inline fun command(
name: String, name: String,
register: Boolean = true, register: Boolean = true,
builder: LiteralArgumentBuilder<ServerCommandSource>.() -> Unit builder: LiteralArgumentBuilder<CommandSourceStack>.() -> Unit
): LiteralArgumentBuilder<ServerCommandSource> = ): LiteralArgumentBuilder<CommandSourceStack> =
LiteralArgumentBuilder.literal<ServerCommandSource>(name).apply(builder).apply { LiteralArgumentBuilder.literal<CommandSourceStack>(name).apply(builder).apply {
if (register) if (register)
BrigardierSupport.commands += this BrigardierSupport.commands += this
} }
@@ -26,7 +26,7 @@ inline fun command(
* *
* @param name the name of the literal * @param name the name of the literal
*/ */
inline fun ArgumentBuilder<ServerCommandSource, *>.literal( inline fun ArgumentBuilder<CommandSourceStack, *>.literal(
name: String, name: String,
builder: LiteralArgumentBuilder<ServerCommandSource>.() -> Unit = {} builder: LiteralArgumentBuilder<CommandSourceStack>.() -> Unit = {}
) = command(name, false, builder).also { then(it) } ) = command(name, false, builder).also { then(it) }

View File

@@ -2,7 +2,7 @@ package net.axay.kspigot.commands
import com.mojang.brigadier.Command import com.mojang.brigadier.Command
import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.ArgumentBuilder
import net.axay.kspigot.commands.internal.ServerCommandSource import net.minecraft.commands.CommandSourceStack
/** /**
* Adds execution logic to this command. The place where this function * Adds execution logic to this command. The place where this function
@@ -11,7 +11,7 @@ import net.axay.kspigot.commands.internal.ServerCommandSource
* *
* @see com.mojang.brigadier.builder.ArgumentBuilder.executes * @see com.mojang.brigadier.builder.ArgumentBuilder.executes
*/ */
inline infix fun ArgumentBuilder<ServerCommandSource, *>.runs( inline infix fun ArgumentBuilder<CommandSourceStack, *>.runs(
crossinline executor: CommandContext.() -> Unit, crossinline executor: CommandContext.() -> Unit,
) = this.apply { ) = this.apply {
executes wrapped@{ executes wrapped@{
@@ -39,6 +39,6 @@ infix fun <S> ArgumentBuilder<S, *>.runs(executor: Command<S>) =
"The name 'simpleExecutes' has been superseded by 'runs'.", "The name 'simpleExecutes' has been superseded by 'runs'.",
ReplaceWith("runs { executor.invoke() }") ReplaceWith("runs { executor.invoke() }")
) )
inline infix fun ArgumentBuilder<ServerCommandSource, *>.simpleExecutes( inline infix fun ArgumentBuilder<CommandSourceStack, *>.simpleExecutes(
crossinline executor: CommandContext.() -> Unit, crossinline executor: CommandContext.() -> Unit,
) = runs(executor) ) = runs(executor)

View File

@@ -4,7 +4,7 @@ import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.builder.LiteralArgumentBuilder
import net.axay.kspigot.annotations.NMS_General import net.axay.kspigot.annotations.NMS_General
import net.axay.kspigot.commands.internal.BrigardierSupport import net.axay.kspigot.commands.internal.BrigardierSupport
import net.minecraft.commands.CommandListenerWrapper import net.minecraft.commands.CommandSourceStack
/** /**
* Registers this command at the [CommandDispatcher] of the server. * Registers this command at the [CommandDispatcher] of the server.
@@ -14,11 +14,11 @@ import net.minecraft.commands.CommandListenerWrapper
* calling this function as the server is starting * calling this function as the server is starting
*/ */
@NMS_General @NMS_General
fun LiteralArgumentBuilder<CommandListenerWrapper>.register(sendToPlayers: Boolean = true) { fun LiteralArgumentBuilder<CommandSourceStack>.register(sendToPlayers: Boolean = true) {
if (!BrigardierSupport.executedDefaultRegistration) if (!BrigardierSupport.executedDefaultRegistration)
BrigardierSupport.commands += this BrigardierSupport.commands += this
else { else {
BrigardierSupport.commandDispatcher.register(this) BrigardierSupport.resolveCommandManager().dispatcher.register(this)
if (sendToPlayers) if (sendToPlayers)
BrigardierSupport.updateCommandTree() BrigardierSupport.updateCommandTree()
} }

View File

@@ -1,14 +1,14 @@
package net.axay.kspigot.commands package net.axay.kspigot.commands
import com.mojang.brigadier.builder.ArgumentBuilder import com.mojang.brigadier.builder.ArgumentBuilder
import net.axay.kspigot.commands.internal.ServerCommandSource import net.minecraft.commands.CommandSourceStack
import org.bukkit.permissions.Permission import org.bukkit.permissions.Permission
/** /**
* Defines that the given [permission] is required to interact with this * Defines that the given [permission] is required to interact with this
* path of the command. * path of the command.
*/ */
fun ArgumentBuilder<ServerCommandSource, *>.requiresPermission(permission: String): ArgumentBuilder<*, *> = fun ArgumentBuilder<CommandSourceStack, *>.requiresPermission(permission: String): ArgumentBuilder<*, *> =
requires { requires {
it.bukkitSender.hasPermission(permission) it.bukkitSender.hasPermission(permission)
} }
@@ -17,7 +17,7 @@ fun ArgumentBuilder<ServerCommandSource, *>.requiresPermission(permission: Strin
* Defines that the given [permission] is required to interact with this * Defines that the given [permission] is required to interact with this
* path of the command. * path of the command.
*/ */
fun ArgumentBuilder<ServerCommandSource, *>.requiresPermission(permission: Permission): ArgumentBuilder<*, *> = fun ArgumentBuilder<CommandSourceStack, *>.requiresPermission(permission: Permission): ArgumentBuilder<*, *> =
requires { requires {
it.bukkitSender.hasPermission(permission) it.bukkitSender.hasPermission(permission)
} }

View File

@@ -2,20 +2,14 @@
package net.axay.kspigot.commands.internal package net.axay.kspigot.commands.internal
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.builder.LiteralArgumentBuilder import com.mojang.brigadier.builder.LiteralArgumentBuilder
import net.axay.kspigot.annotations.NMS_1_17
import net.axay.kspigot.annotations.NMS_General
import net.axay.kspigot.event.listen import net.axay.kspigot.event.listen
import net.axay.kspigot.extensions.onlinePlayers import net.axay.kspigot.extensions.onlinePlayers
import net.axay.kspigot.extensions.server import net.axay.kspigot.extensions.server
import net.axay.kspigot.main.KSpigotMainInstance import net.axay.kspigot.main.KSpigotMainInstance
import net.axay.kspigot.utils.reflectField import net.minecraft.commands.CommandSourceStack
import net.minecraft.commands.CommandListenerWrapper
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
typealias ServerCommandSource = CommandListenerWrapper
/** /**
* This class provides Brigardier support. It does that * This class provides Brigardier support. It does that
* by using reflection once. Additionally, this class is * by using reflection once. Additionally, this class is
@@ -23,7 +17,7 @@ typealias ServerCommandSource = CommandListenerWrapper
*/ */
object BrigardierSupport { object BrigardierSupport {
@PublishedApi @PublishedApi
internal val commands = LinkedHashSet<LiteralArgumentBuilder<CommandListenerWrapper>>() internal val commands = LinkedHashSet<LiteralArgumentBuilder<CommandSourceStack>>()
internal var executedDefaultRegistration = false internal var executedDefaultRegistration = false
private set private set
@@ -38,45 +32,27 @@ object BrigardierSupport {
} }
} }
/** @Suppress("HasPlatformType")
* The command manager is used to hold the command dispatcher, fun resolveCommandManager() = (server as org.bukkit.craftbukkit.v1_18_R1.CraftServer)
* and to manage and dispatch the brigardier commands for .server.vanillaCommandDispatcher
* all players on the server.
*/
@Suppress("HasPlatformType") // do not refer non-lazily to the type in this class
@NMS_General
val commandManager by lazy {
(server as org.bukkit.craftbukkit.v1_17_R1.CraftServer).server.vanillaCommandDispatcher
}
/**
* The command dispatcher is used to register brigardier commands.
*/
@NMS_1_17
val commandDispatcher by lazy {
// g = the command dispatcher
commandManager.reflectField<CommandDispatcher<CommandListenerWrapper>>("g")
}
@NMS_General
internal fun registerAll() { internal fun registerAll() {
executedDefaultRegistration = true executedDefaultRegistration = true
// TODO unregister commands which are now missing due to a possible reload // TODO unregister commands which are now missing due to a possible reload
if (commands.isNotEmpty()) { if (commands.isNotEmpty()) {
commands.forEach { commands.forEach {
commandDispatcher.register(it) resolveCommandManager().dispatcher.register(it)
} }
if (onlinePlayers.isNotEmpty()) if (onlinePlayers.isNotEmpty())
updateCommandTree() updateCommandTree()
} }
} }
@NMS_General
fun updateCommandTree() { fun updateCommandTree() {
onlinePlayers.forEach { onlinePlayers.forEach {
// send the command tree // send the command tree
commandManager.a((it as org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer).handle) resolveCommandManager().sendCommands((it as org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer).handle)
} }
} }
} }

View File

@@ -0,0 +1,27 @@
package net.axay.kspigot.data
import net.axay.kspigot.annotations.NMS_General
import net.minecraft.nbt.CompoundTag
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.entity.Entity
import org.bukkit.inventory.ItemStack
@NMS_General
var Entity.nbtData: CompoundTag
get() {
val nbtTagCompound = CompoundTag()
(this as CraftEntity).handle.save(nbtTagCompound)
return nbtTagCompound
}
set(value) {
(this as CraftEntity).handle.load(value)
}
@NMS_General
val ItemStack.nbtData: CompoundTag
get() {
CraftItemStack.asNMSCopy(this).let {
return if (it.hasTag()) (it.tag ?: CompoundTag()) else CompoundTag()
}
}

View File

@@ -9,7 +9,6 @@ import net.md_5.bungee.api.ChatMessageType
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.attribute.Attribute import org.bukkit.attribute.Attribute
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld
import org.bukkit.entity.* import org.bukkit.entity.*
import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.EquipmentSlot
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@@ -102,21 +101,15 @@ fun Player.showOnlinePlayers() {
onlinePlayers.filter { it != this }.forEach { this.showPlayer(PluginInstance, it) } onlinePlayers.filter { it != this }.forEach { this.showPlayer(PluginInstance, it) }
} }
/**
* Kicks the player from the server.
*/
fun Player.kick(reason: String? = "You got kicked!") {
kickPlayer(reason)
}
/** /**
* Spawns an entity without any variations in color, type etc... * Spawns an entity without any variations in color, type etc...
*/ */
@Deprecated("This function is unstable and it cannot be guaranteed that it will work at any time in the future.")
@NMS_General @NMS_General
fun Location.spawnCleanEntity(entityType: EntityType): Entity? { fun Location.spawnCleanEntity(entityType: EntityType): Entity? {
val craftWorld = world as? CraftWorld ?: return null val craftWorld = world as? org.bukkit.craftbukkit.v1_18_R1.CraftWorld ?: return null
return craftWorld.createEntity(this, entityType.entityClass)?.let { return craftWorld.createEntity(this, entityType.entityClass)?.let {
craftWorld.handle.addEntity(it) craftWorld.handle.addFreshEntity(it)
return@let it.bukkitEntity return@let it.bukkitEntity
} }
} }
@@ -135,6 +128,7 @@ fun Player.title(
stay: Int = 70, stay: Int = 70,
fadeOut: Int = 20, fadeOut: Int = 20,
) { ) {
@Suppress("DEPRECATION")
sendTitle(mainText, subText, fadeIn, stay, fadeOut) sendTitle(mainText, subText, fadeIn, stay, fadeOut)
} }

View File

@@ -1,15 +1,16 @@
package net.axay.kspigot.structures package net.axay.kspigot.structures
import net.axay.kspigot.annotations.NMS_General import net.axay.kspigot.annotations.NMS_General
import net.axay.kspigot.data.NBTData
import net.axay.kspigot.data.nbtData import net.axay.kspigot.data.nbtData
import net.axay.kspigot.extensions.bukkit.spawnCleanEntity import net.axay.kspigot.extensions.bukkit.spawnCleanEntity
import net.axay.kspigot.extensions.geometry.SimpleLocation3D import net.axay.kspigot.extensions.geometry.SimpleLocation3D
import net.axay.kspigot.particles.KSpigotParticle import net.axay.kspigot.particles.KSpigotParticle
import net.minecraft.nbt.CompoundTag
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.block.Block import org.bukkit.block.Block
import org.bukkit.block.data.BlockData import org.bukkit.block.data.BlockData
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
import org.bukkit.entity.Entity import org.bukkit.entity.Entity
import org.bukkit.entity.EntityType import org.bukkit.entity.EntityType
@@ -54,13 +55,13 @@ data class StructureDataBlock(
@NMS_General @NMS_General
data class StructureDataEntity( data class StructureDataEntity(
val entityType: EntityType, val entityType: EntityType,
val nbtData: NBTData, val nbtData: CompoundTag,
) : StructureData { ) : StructureData {
constructor(entity: Entity) : this(entity.type, entity.nbtData) constructor(entity: Entity) : this(entity.type, entity.nbtData)
constructor(entityType: EntityType) : this(entityType, NBTData()) constructor(entityType: EntityType) : this(entityType, CompoundTag())
override fun createAt(loc: Location) { override fun createAt(loc: Location) {
loc.spawnCleanEntity(entityType)?.nbtData = nbtData (loc.spawnCleanEntity(entityType) as CraftEntity).handle.load(nbtData)
} }
} }