Refactor and improve a lot of the API. Move default implementations into a package. Reformatting.
This commit is contained in:
@@ -16,10 +16,10 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
|
||||
|
||||
override fun getPlugin(): Plugin = plugin
|
||||
override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver {
|
||||
return getParcelCommandReceiver(plugin.worlds, context, target, cmdName)
|
||||
return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
|
||||
}
|
||||
|
||||
protected inline val worlds get() = plugin.worlds
|
||||
protected inline val worlds get() = plugin.parcelProvider
|
||||
|
||||
protected fun error(message: String): Nothing {
|
||||
throw CommandException(message)
|
||||
@@ -32,7 +32,7 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
|
||||
protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
|
||||
if (player.hasAdminManage) return
|
||||
val numOwnedParcels = plugin.storage.getOwnedParcels(ParcelOwner(player)).await()
|
||||
.filter { it.world.world == world.world }.size
|
||||
.filter { it.worldId.equals(world.id) }.size
|
||||
|
||||
val limit = player.parcelLimit
|
||||
if (numOwnedParcels >= limit) {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.dico.parcels2.command
|
||||
|
||||
import io.dico.dicore.command.Validate
|
||||
import io.dico.dicore.command.annotation.Cmd
|
||||
import io.dico.dicore.command.annotation.Desc
|
||||
import io.dico.parcels2.GlobalAddedData
|
||||
import io.dico.parcels2.GlobalAddedDataManager
|
||||
import io.dico.parcels2.ParcelOwner
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class CommandsAddedStatusGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
private inline val data get() = plugin.globalAddedData
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline operator fun GlobalAddedDataManager.get(player: OfflinePlayer): GlobalAddedData = data[ParcelOwner(player)]
|
||||
|
||||
@Cmd("allow", aliases = ["add", "permit"])
|
||||
@Desc("Globally allows a player to build on all",
|
||||
"the parcels that you own.",
|
||||
shortVersion = "globally allows a player to build on your parcels")
|
||||
@ParcelRequire(owner = true)
|
||||
fun cmdAllow(sender: Player, player: OfflinePlayer): Any? {
|
||||
Validate.isTrue(player != sender, "The target cannot be yourself")
|
||||
Validate.isTrue(data[sender].allow(player), "${player.name} is already allowed globally")
|
||||
return "${player.name} is now allowed to build on all your parcels"
|
||||
}
|
||||
|
||||
@Cmd("disallow", aliases = ["remove", "forbid"])
|
||||
@Desc("Globally disallows a player to build on",
|
||||
"the parcels that you own.",
|
||||
"If the player is allowed to build on specific",
|
||||
"parcels, they can still build there.",
|
||||
shortVersion = "globally disallows a player to build on your parcels")
|
||||
@ParcelRequire(owner = true)
|
||||
fun cmdDisallow(sender: Player, player: OfflinePlayer): Any? {
|
||||
Validate.isTrue(player != sender, "The target cannot be yourself")
|
||||
Validate.isTrue(data[sender].disallow(player), "${player.name} is not currently allowed globally")
|
||||
return "${player.name} is not allowed to build on all your parcels anymore"
|
||||
}
|
||||
|
||||
@Cmd("ban", aliases = ["deny"])
|
||||
@Desc("Globally bans a player from all the parcels",
|
||||
"that you own, making them unable to enter.",
|
||||
shortVersion = "globally bans a player from your parcels")
|
||||
@ParcelRequire(owner = true)
|
||||
fun cmdBan(sender: Player, player: OfflinePlayer): Any? {
|
||||
Validate.isTrue(player != sender, "The target cannot be yourself")
|
||||
Validate.isTrue(data[sender].ban(player), "${player.name} is already banned from all your parcels")
|
||||
return "${player.name} is now banned from all your parcels"
|
||||
}
|
||||
|
||||
@Cmd("unban", aliases = ["undeny"])
|
||||
@Desc("Globally unbans a player from all the parcels",
|
||||
"that you own, they can enter again.",
|
||||
"If the player is banned from specific parcels,",
|
||||
"they will still be banned there.",
|
||||
shortVersion = "globally unbans a player from your parcels")
|
||||
@ParcelRequire(owner = true)
|
||||
fun cmdUnban(sender: Player, player: OfflinePlayer): Any? {
|
||||
Validate.isTrue(data[sender].unban(player), "${player.name} is not currently banned from all your parcels")
|
||||
return "${player.name} is not banned from all your parcels anymore"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import io.dico.parcels2.util.hasAdminManage
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class CommandsAddedStatus(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
class CommandsAddedStatusLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
|
||||
@Cmd("allow", aliases = ["add", "permit"])
|
||||
@Desc("Allows a player to build on this parcel",
|
||||
@@ -9,7 +9,7 @@ import io.dico.parcels2.blockvisitor.RegionTraversal
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
import java.util.Random
|
||||
|
||||
class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
|
||||
@@ -39,7 +39,8 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
server.createBlockData(Material.QUARTZ_BLOCK)
|
||||
)
|
||||
val random = Random()
|
||||
world.generator.doBlockOperation(parcel, direction = RegionTraversal.UPWARD) { block ->
|
||||
|
||||
world.doBlockOperation(parcel.id, direction = RegionTraversal.UPWARD) { block ->
|
||||
block.blockData = blockDatas[random.nextInt(4)]
|
||||
}.onProgressUpdate(1000, 1000) { progress, elapsedTime ->
|
||||
context.sendMessage(EMessageType.INFORMATIVE, "Mess progress: %.02f%%, %.2fs elapsed"
|
||||
|
||||
@@ -8,7 +8,6 @@ import io.dico.dicore.command.annotation.Flag
|
||||
import io.dico.dicore.command.annotation.RequireParameters
|
||||
import io.dico.parcels2.ParcelOwner
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.storage.getParcelBySerializedValue
|
||||
import io.dico.parcels2.util.hasAdminManage
|
||||
import io.dico.parcels2.util.hasParcelHomeOthers
|
||||
import io.dico.parcels2.util.uuid
|
||||
@@ -27,7 +26,7 @@ class CommandsGeneral(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
val parcel = world.nextEmptyParcel()
|
||||
?: error("This world is full, please ask an admin to upsize it")
|
||||
parcel.owner = ParcelOwner(uuid = player.uuid)
|
||||
player.teleport(parcel.homeLocation)
|
||||
player.teleport(parcel.world.getHomeLocation(parcel.id))
|
||||
return "Enjoy your new parcel!"
|
||||
}
|
||||
|
||||
@@ -53,13 +52,13 @@ class CommandsGeneral(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
val ownedParcelsResult = plugin.storage.getOwnedParcels(ownerTarget.owner).await()
|
||||
|
||||
val ownedParcels = ownedParcelsResult
|
||||
.map { worlds.getParcelBySerializedValue(it) }
|
||||
.map { worlds.getParcelById(it) }
|
||||
.filter { it != null && ownerTarget.world == it.world }
|
||||
|
||||
val targetMatch = ownedParcels.getOrNull(target.index)
|
||||
?: error("The specified parcel could not be matched")
|
||||
|
||||
player.teleport(targetMatch.homeLocation)
|
||||
player.teleport(targetMatch.world.getHomeLocation(targetMatch.id))
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -91,7 +90,7 @@ class CommandsGeneral(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||
if (!sure) return "Are you sure? You cannot undo this action!\n" +
|
||||
"Type ${context.rawInput} -sure if you want to go through with this."
|
||||
|
||||
world.generator.clearParcel(parcel)
|
||||
world.clearParcel(parcel.id)
|
||||
.onProgressUpdate(1000, 1000) { progress, elapsedTime ->
|
||||
context.sendMessage(EMessageType.INFORMATIVE, "Clear progress: %.02f%%, %.2fs elapsed"
|
||||
.format(progress * 100, elapsedTime / 1000.0))
|
||||
|
||||
@@ -3,29 +3,32 @@ package io.dico.parcels2.command
|
||||
import io.dico.dicore.command.CommandBuilder
|
||||
import io.dico.dicore.command.ICommandAddress
|
||||
import io.dico.dicore.command.ICommandDispatcher
|
||||
import io.dico.dicore.command.predef.PredefinedCommand
|
||||
import io.dico.dicore.command.registration.reflect.ReflectiveRegistration
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.logger
|
||||
import java.util.*
|
||||
import java.util.LinkedList
|
||||
import java.util.Queue
|
||||
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher {
|
||||
//@formatter:off
|
||||
return CommandBuilder()
|
||||
.setChatController(ParcelsChatController())
|
||||
.addParameterType(false, ParcelParameterType(plugin.worlds))
|
||||
.addParameterType(true, ParcelTarget.PType(plugin.worlds))
|
||||
.addParameterType(false, ParcelParameterType(plugin.parcelProvider))
|
||||
.addParameterType(true, ParcelTarget.PType(plugin.parcelProvider))
|
||||
|
||||
.group("parcel", "plot", "plots", "p")
|
||||
.registerCommands(CommandsGeneral(plugin))
|
||||
.registerCommands(CommandsAddedStatus(plugin))
|
||||
.registerCommands(CommandsAddedStatusLocal(plugin))
|
||||
|
||||
.group("option")
|
||||
.group("option", "opt", "o")
|
||||
//.apply { CommandsParcelOptions.setGroupDescription(this) }
|
||||
.registerCommands(CommandsParcelOptions(plugin))
|
||||
.parent()
|
||||
|
||||
.group("global", "g")
|
||||
.registerCommands(CommandsAddedStatusGlobal(plugin))
|
||||
.parent()
|
||||
|
||||
.group("admin", "a")
|
||||
.registerCommands(CommandsAdmin(plugin))
|
||||
.parent()
|
||||
|
||||
@@ -5,8 +5,8 @@ import io.dico.dicore.command.ExecutionContext
|
||||
import io.dico.dicore.command.ICommandReceiver
|
||||
import io.dico.dicore.command.Validate
|
||||
import io.dico.parcels2.Parcel
|
||||
import io.dico.parcels2.ParcelProvider
|
||||
import io.dico.parcels2.ParcelWorld
|
||||
import io.dico.parcels2.Worlds
|
||||
import io.dico.parcels2.util.hasAdminManage
|
||||
import io.dico.parcels2.util.uuid
|
||||
import org.bukkit.entity.Player
|
||||
@@ -30,7 +30,7 @@ open class ParcelScope(val parcel: Parcel) : WorldScope(parcel.world) {
|
||||
"You must own this parcel to $action")
|
||||
}
|
||||
|
||||
fun getParcelCommandReceiver(worlds: Worlds, context: ExecutionContext, method: Method, cmdName: String): ICommandReceiver {
|
||||
fun getParcelCommandReceiver(parcelProvider: ParcelProvider, context: ExecutionContext, method: Method, cmdName: String): ICommandReceiver {
|
||||
val player = context.sender as Player
|
||||
val function = method.kotlinFunction!!
|
||||
val receiverType = function.extensionReceiverParameter!!.type
|
||||
@@ -39,20 +39,20 @@ fun getParcelCommandReceiver(worlds: Worlds, context: ExecutionContext, method:
|
||||
val owner = require?.owner == true
|
||||
|
||||
return when (receiverType.jvmErasure) {
|
||||
ParcelScope::class -> ParcelScope(worlds.getParcelRequired(player, admin, owner))
|
||||
WorldScope::class -> WorldScope(worlds.getWorldRequired(player, admin))
|
||||
ParcelScope::class -> ParcelScope(parcelProvider.getParcelRequired(player, admin, owner))
|
||||
WorldScope::class -> WorldScope(parcelProvider.getWorldRequired(player, admin))
|
||||
else -> throw InternalError("Invalid command receiver type")
|
||||
}
|
||||
}
|
||||
|
||||
fun Worlds.getWorldRequired(player: Player, admin: Boolean = false): ParcelWorld {
|
||||
fun ParcelProvider.getWorldRequired(player: Player, admin: Boolean = false): ParcelWorld {
|
||||
if (admin) Validate.isTrue(player.hasAdminManage, "You must have admin rights to use that command")
|
||||
return getWorld(player.world)
|
||||
?: throw CommandException("You must be in a parcel world to use that command")
|
||||
}
|
||||
|
||||
fun Worlds.getParcelRequired(player: Player, admin: Boolean = false, own: Boolean = false): Parcel {
|
||||
val parcel = getWorldRequired(player, admin = admin).parcelAt(player)
|
||||
fun ParcelProvider.getParcelRequired(player: Player, admin: Boolean = false, own: Boolean = false): Parcel {
|
||||
val parcel = getWorldRequired(player, admin = admin).getParcelAt(player)
|
||||
?: throw CommandException("You must be in a parcel to use that command")
|
||||
if (own) Validate.isTrue(parcel.isOwner(player.uuid) || player.hasAdminManage,
|
||||
"You must own this parcel to use that command")
|
||||
|
||||
@@ -3,15 +3,10 @@ package io.dico.parcels2.command
|
||||
import io.dico.dicore.command.CommandException
|
||||
import io.dico.dicore.command.parameter.ArgumentBuffer
|
||||
import io.dico.dicore.command.parameter.Parameter
|
||||
import io.dico.dicore.command.parameter.type.ParameterConfig
|
||||
import io.dico.dicore.command.parameter.type.ParameterType
|
||||
import io.dico.parcels2.Parcel
|
||||
import io.dico.parcels2.ParcelProvider
|
||||
import io.dico.parcels2.ParcelWorld
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.Worlds
|
||||
import io.dico.parcels2.util.isValid
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
@@ -19,7 +14,7 @@ fun invalidInput(parameter: Parameter<*, *>, message: String): Nothing {
|
||||
throw CommandException("invalid input for ${parameter.name}: $message")
|
||||
}
|
||||
|
||||
fun Worlds.getTargetWorld(input: String?, sender: CommandSender, parameter: Parameter<*, *>): ParcelWorld {
|
||||
fun ParcelProvider.getTargetWorld(input: String?, sender: CommandSender, parameter: Parameter<*, *>): ParcelWorld {
|
||||
val worldName = input
|
||||
?.takeUnless { it.isEmpty() }
|
||||
?: (sender as? Player)?.world?.name
|
||||
@@ -29,14 +24,14 @@ fun Worlds.getTargetWorld(input: String?, sender: CommandSender, parameter: Para
|
||||
?: invalidInput(parameter, "$worldName is not a parcel world")
|
||||
}
|
||||
|
||||
class ParcelParameterType(val worlds: Worlds) : ParameterType<Parcel, Void>(Parcel::class.java) {
|
||||
class ParcelParameterType(val parcelProvider: ParcelProvider) : ParameterType<Parcel, Void>(Parcel::class.java) {
|
||||
val regex = Regex.fromLiteral("((.+)->)?([0-9]+):([0-9]+)")
|
||||
|
||||
override fun parse(parameter: Parameter<Parcel, Void>, sender: CommandSender, buffer: ArgumentBuffer): Parcel {
|
||||
val matchResult = regex.matchEntire(buffer.next())
|
||||
?: invalidInput(parameter, "must match (w->)?a:b (/${regex.pattern}/)")
|
||||
|
||||
val world = worlds.getTargetWorld(matchResult.groupValues[2], sender, parameter)
|
||||
val world = parcelProvider.getTargetWorld(matchResult.groupValues[2], sender, parameter)
|
||||
|
||||
val x = matchResult.groupValues[3].toIntOrNull()
|
||||
?: invalidInput(parameter, "couldn't parse int")
|
||||
@@ -44,7 +39,7 @@ class ParcelParameterType(val worlds: Worlds) : ParameterType<Parcel, Void>(Parc
|
||||
val z = matchResult.groupValues[4].toIntOrNull()
|
||||
?: invalidInput(parameter, "couldn't parse int")
|
||||
|
||||
return world.parcelByID(x, z)
|
||||
return world.getParcelById(x, z)
|
||||
?: invalidInput(parameter, "parcel id is out of range")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import io.dico.dicore.command.parameter.Parameter
|
||||
import io.dico.dicore.command.parameter.type.ParameterConfig
|
||||
import io.dico.dicore.command.parameter.type.ParameterType
|
||||
import io.dico.parcels2.*
|
||||
import io.dico.parcels2.storage.getParcelBySerializedValue
|
||||
import io.dico.parcels2.util.Vec2i
|
||||
import io.dico.parcels2.util.floor
|
||||
import io.dico.parcels2.util.isValid
|
||||
@@ -20,7 +19,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
|
||||
class ByID(world: ParcelWorld, val id: Vec2i?, isDefault: Boolean) : ParcelTarget(world, isDefault) {
|
||||
override suspend fun ParcelsPlugin.getParcelSuspend(): Parcel? = getParcel()
|
||||
fun getParcel() = id?.let { world.parcelByID(it) }
|
||||
fun getParcel() = id?.let { world.getParcelById(it) }
|
||||
val isPath: Boolean get() = id == null
|
||||
}
|
||||
|
||||
@@ -32,7 +31,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
override suspend fun ParcelsPlugin.getParcelSuspend(): Parcel? {
|
||||
val ownedParcelsSerialized = storage.getOwnedParcels(owner).await()
|
||||
val ownedParcels = ownedParcelsSerialized
|
||||
.map { worlds.getParcelBySerializedValue(it) }
|
||||
.map { parcelProvider.getParcelById(it) }
|
||||
.filter { it != null && world == it.world && owner == it.owner }
|
||||
return ownedParcels.getOrNull(index)
|
||||
}
|
||||
@@ -59,7 +58,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
// instead of parcel that the player is in
|
||||
}
|
||||
|
||||
class PType(val worlds: Worlds) : ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, ParcelTarget.Config) {
|
||||
class PType(val parcelProvider: ParcelProvider) : ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, ParcelTarget.Config) {
|
||||
|
||||
override fun parse(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget {
|
||||
var input = buffer.next()
|
||||
@@ -68,19 +67,19 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
|
||||
val world = if (worldString.isEmpty()) {
|
||||
val player = requirePlayer(sender, parameter, "the world")
|
||||
worlds.getWorld(player.world)
|
||||
parcelProvider.getWorld(player.world)
|
||||
?: invalidInput(parameter, "You cannot omit the world if you're not in a parcel world")
|
||||
} else {
|
||||
worlds.getWorld(worldString) ?: invalidInput(parameter, "$worldString is not a parcel world")
|
||||
parcelProvider.getWorld(worldString) ?: invalidInput(parameter, "$worldString is not a parcel world")
|
||||
}
|
||||
|
||||
val kind = parameter.paramInfo ?: DEFAULT_KIND
|
||||
if (input.contains(',')) {
|
||||
if (kind and ID == 0) invalidInput(parameter, "You must specify a parcel by ID, that is, the x and z component separated by a comma")
|
||||
if (kind and ID == 0) invalidInput(parameter, "You must specify a parcel by OWNER, that is, an owner and index")
|
||||
return ByID(world, getId(parameter, input), false)
|
||||
}
|
||||
|
||||
if (kind and OWNER == 0) invalidInput(parameter, "You must specify a parcel by OWNER, that is, an owner and index")
|
||||
if (kind and OWNER == 0) invalidInput(parameter, "You must specify a parcel by ID, that is, the x and z component separated by a comma")
|
||||
val (owner, index) = getHomeIndex(parameter, sender, input)
|
||||
return ByOwner(world, owner, index, false)
|
||||
}
|
||||
@@ -106,7 +105,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
indexString = input
|
||||
} else {
|
||||
ownerString = input.substring(0, splitIdx)
|
||||
indexString = input.substring(0, splitIdx + 1)
|
||||
indexString = input.substring(splitIdx + 1)
|
||||
}
|
||||
|
||||
val owner = if (ownerString.isEmpty())
|
||||
@@ -151,9 +150,9 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
|
||||
}
|
||||
|
||||
val player = requirePlayer(sender, parameter, "the parcel")
|
||||
val world = worlds.getWorld(player.world) ?: invalidInput(parameter, "You must be in a parcel world to omit the parcel")
|
||||
val world = parcelProvider.getWorld(player.world) ?: invalidInput(parameter, "You must be in a parcel world to omit the parcel")
|
||||
if (useLocation) {
|
||||
val id = player.location.let { world.generator.parcelIDAt(it.x.floor(), it.z.floor()) }
|
||||
val id = player.location.let { world.getParcelIdAt(it.x.floor(), it.z.floor())?.pos }
|
||||
return ByID(world, id, true)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user