summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/command
diff options
context:
space:
mode:
authorDico Karssiens <dico.karssiens@gmail.com>2018-11-11 14:06:45 +0000
committerDico Karssiens <dico.karssiens@gmail.com>2018-11-11 14:06:45 +0000
commit0f196f59c6a4cb76ab8409da62ff1f35505f94a8 (patch)
tree4b612eb874fc3b7aebe88430a28f1bfc7272c9a6 /src/main/kotlin/io/dico/parcels2/command
parente55c595e54116961798cec03f6404d0c8d986e6d (diff)
Changes I made before breaking my local repository. Hoping this works.dev
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/command')
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt126
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt188
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt262
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt322
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt282
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt152
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt286
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt274
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt136
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt112
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt166
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt382
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt46
13 files changed, 1367 insertions, 1367 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
index eaa9f57..32f4299 100644
--- a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
@@ -1,64 +1,64 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.*
-import io.dico.dicore.command.registration.reflect.ICommandInterceptor
-import io.dico.dicore.command.registration.reflect.ICommandReceiver
-import io.dico.parcels2.*
-import io.dico.parcels2.PlayerProfile.Real
-import io.dico.parcels2.PlayerProfile.Unresolved
-import io.dico.parcels2.util.ext.hasPermAdminManage
-import io.dico.parcels2.util.ext.parcelLimit
-import org.bukkit.entity.Player
-import org.bukkit.plugin.Plugin
-import java.lang.reflect.Method
-
-abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandInterceptor {
-
- override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver {
- return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
- }
-
- override fun getCoroutineContext(context: ExecutionContext?, target: Method?, cmdName: String?): Any {
- return plugin.coroutineContext
- }
-
- protected fun checkConnected(action: String) {
- if (!plugin.storage.isConnected) err("Parcels cannot $action right now because of a database error")
- }
-
- protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
- if (player.hasPermAdminManage) return
- val numOwnedParcels = plugin.storage.getOwnedParcels(PlayerProfile(player)).await()
- .filter { it.worldId.equals(world.id) }.size
-
- val limit = player.parcelLimit
- if (numOwnedParcels >= limit) {
- err("You have enough plots for now")
- }
- }
-
- protected suspend fun toPrivilegeKey(profile: PlayerProfile): PrivilegeKey = when (profile) {
- is Real -> profile
- is Unresolved -> profile.tryResolveSuspendedly(plugin.storage)
- ?: throw CommandException()
- else -> throw CommandException()
- }
-
- protected fun areYouSureMessage(context: ExecutionContext): String {
- val command = (context.route + context.original).joinToString(" ") + " -sure"
- return "Are you sure? You cannot undo this action!\n" +
- "Run \"/$command\" if you want to go through with this."
- }
-
- protected fun Job.reportProgressUpdates(context: ExecutionContext, action: String): Job =
- onProgressUpdate(1000, 1000) { progress, elapsedTime ->
- val alt = context.getFormat(EMessageType.NUMBER)
- val main = context.getFormat(EMessageType.INFORMATIVE)
- context.sendMessage(
- EMessageType.INFORMATIVE, false, "$action progress: $alt%.02f$main%%, $alt%.2f${main}s elapsed"
- .format(progress * 100, elapsedTime / 1000.0)
- )
- }
-}
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.*
+import io.dico.dicore.command.registration.reflect.ICommandInterceptor
+import io.dico.dicore.command.registration.reflect.ICommandReceiver
+import io.dico.parcels2.*
+import io.dico.parcels2.PlayerProfile.Real
+import io.dico.parcels2.PlayerProfile.Unresolved
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import io.dico.parcels2.util.ext.parcelLimit
+import org.bukkit.entity.Player
+import org.bukkit.plugin.Plugin
+import java.lang.reflect.Method
+
+abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandInterceptor {
+
+ override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver {
+ return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
+ }
+
+ override fun getCoroutineContext(context: ExecutionContext?, target: Method?, cmdName: String?): Any {
+ return plugin.coroutineContext
+ }
+
+ protected fun checkConnected(action: String) {
+ if (!plugin.storage.isConnected) err("Parcels cannot $action right now because of a database error")
+ }
+
+ protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
+ if (player.hasPermAdminManage) return
+ val numOwnedParcels = plugin.storage.getOwnedParcels(PlayerProfile(player)).await()
+ .filter { it.worldId.equals(world.id) }.size
+
+ val limit = player.parcelLimit
+ if (numOwnedParcels >= limit) {
+ err("You have enough plots for now")
+ }
+ }
+
+ protected suspend fun toPrivilegeKey(profile: PlayerProfile): PrivilegeKey = when (profile) {
+ is Real -> profile
+ is Unresolved -> profile.tryResolveSuspendedly(plugin.storage)
+ ?: throw CommandException()
+ else -> throw CommandException()
+ }
+
+ protected fun areYouSureMessage(context: ExecutionContext): String {
+ val command = (context.route + context.original).joinToString(" ") + " -sure"
+ return "Are you sure? You cannot undo this action!\n" +
+ "Run \"/$command\" if you want to go through with this."
+ }
+
+ protected fun Job.reportProgressUpdates(context: ExecutionContext, action: String): Job =
+ onProgressUpdate(1000, 1000) { progress, elapsedTime ->
+ val alt = context.getFormat(EMessageType.NUMBER)
+ val main = context.getFormat(EMessageType.INFORMATIVE)
+ context.sendMessage(
+ EMessageType.INFORMATIVE, false, "$action progress: $alt%.02f$main%%, $alt%.2f${main}s elapsed"
+ .format(progress * 100, elapsedTime / 1000.0)
+ )
+ }
+}
+
fun err(message: String): Nothing = throw CommandException(message) \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt
index e700d6d..38adc43 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt
@@ -1,95 +1,95 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.CommandException
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.Validate
-import io.dico.dicore.command.annotation.Cmd
-import io.dico.dicore.command.annotation.Flag
-import io.dico.parcels2.*
-import io.dico.parcels2.command.ParcelTarget.TargetKind
-import io.dico.parcels2.defaultimpl.DefaultParcelContainer
-import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
-
-class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
-
- @Cmd("setowner")
- @RequireParcelPrivilege(Privilege.ADMIN)
- suspend fun ParcelScope.cmdSetowner(@ProfileKind(ProfileKind.ANY) target: PlayerProfile): Any? {
- val profile = target.resolved(plugin.storage, resolveToFake = true)!!
- parcel.owner = profile
-
- val fakeString = if (profile.isFake) " (fake)" else ""
- return "${profile.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
- }
-
- @Cmd("update_all_owner_signs")
- fun cmdUpdateAllOwnerSigns(context: ExecutionContext): Any? {
- Validate.isAuthorized(context.sender, PERM_ADMIN_MANAGE)
- plugin.jobDispatcher.dispatch {
- fun getParcelCount(world: ParcelWorld) = (world.options.axisLimit * 2 + 1).let { it * it }
- val parcelCount = plugin.parcelProvider.worlds.values.sumBy { getParcelCount(it) }.toDouble()
- var processed = 0
- for (world in plugin.parcelProvider.worlds.values) {
- markSuspensionPoint()
-
- val container = world.container as? DefaultParcelContainer
- if (container == null) {
- processed += getParcelCount(world)
- setProgress(processed / parcelCount)
- continue
- }
-
- for (parcel in container.getAllParcels()) {
- parcel.updateOwnerSign(force = true)
- processed++
- setProgress(processed / parcelCount)
- }
- }
- }.reportProgressUpdates(context, "Updating")
- return null
- }
-
- @Cmd("dispose")
- @RequireParcelPrivilege(Privilege.ADMIN)
- fun ParcelScope.cmdDispose(): Any? {
- parcel.dispose()
- return "Data of (${parcel.id.idString}) has been disposed"
- }
-
- @Cmd("reset")
- @RequireParcelPrivilege(Privilege.ADMIN)
- fun ParcelScope.cmdReset(context: ExecutionContext, @Flag sure: Boolean): Any? {
- Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
- if (!sure) return areYouSureMessage(context)
-
- parcel.dispose()
- world.blockManager.clearParcel(parcel.id)?.reportProgressUpdates(context, "Reset")
- return "Data of (${parcel.id.idString}) has been disposed"
- }
-
- @Cmd("swap")
- @RequireParcelPrivilege(Privilege.ADMIN)
- fun ParcelScope.cmdSwap(
- context: ExecutionContext,
- @TargetKind(TargetKind.ID) target: ParcelTarget,
- @Flag sure: Boolean
- ): Any? {
- Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
- if (!sure) return areYouSureMessage(context)
-
- val parcel2 = (target as ParcelTarget.ByID).getParcel()
- ?: throw CommandException("Invalid parcel target")
-
- // Validate.isTrue(parcel2.world == world, "Parcel must be in the same world")
- Validate.isTrue(!parcel2.hasBlockVisitors, "A process is already running in that parcel")
-
- val data = parcel.data
- parcel.copyData(parcel2.data)
- parcel2.copyData(data)
-
- val job = plugin.parcelProvider.swapParcels(parcel.id, parcel2.id)?.reportProgressUpdates(context, "Swap")
- Validate.notNull(job, "A process is already running in some parcel (internal error)")
- return null
- }
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.CommandException
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.Validate
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.Flag
+import io.dico.parcels2.*
+import io.dico.parcels2.command.ParcelTarget.TargetKind
+import io.dico.parcels2.defaultimpl.DefaultParcelContainer
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
+
+class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
+
+ @Cmd("setowner")
+ @RequireParcelPrivilege(Privilege.ADMIN)
+ suspend fun ParcelScope.cmdSetowner(@ProfileKind(ProfileKind.ANY) target: PlayerProfile): Any? {
+ val profile = target.resolved(plugin.storage, resolveToFake = true)!!
+ parcel.owner = profile
+
+ val fakeString = if (profile.isFake) " (fake)" else ""
+ return "${profile.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
+ }
+
+ @Cmd("update_all_owner_signs")
+ fun cmdUpdateAllOwnerSigns(context: ExecutionContext): Any? {
+ Validate.isAuthorized(context.sender, PERM_ADMIN_MANAGE)
+ plugin.jobDispatcher.dispatch {
+ fun getParcelCount(world: ParcelWorld) = (world.options.axisLimit * 2 + 1).let { it * it }
+ val parcelCount = plugin.parcelProvider.worlds.values.sumBy { getParcelCount(it) }.toDouble()
+ var processed = 0
+ for (world in plugin.parcelProvider.worlds.values) {
+ markSuspensionPoint()
+
+ val container = world.container as? DefaultParcelContainer
+ if (container == null) {
+ processed += getParcelCount(world)
+ setProgress(processed / parcelCount)
+ continue
+ }
+
+ for (parcel in container.getAllParcels()) {
+ parcel.updateOwnerSign(force = true)
+ processed++
+ setProgress(processed / parcelCount)
+ }
+ }
+ }.reportProgressUpdates(context, "Updating")
+ return null
+ }
+
+ @Cmd("dispose")
+ @RequireParcelPrivilege(Privilege.ADMIN)
+ fun ParcelScope.cmdDispose(): Any? {
+ parcel.dispose()
+ return "Data of (${parcel.id.idString}) has been disposed"
+ }
+
+ @Cmd("reset")
+ @RequireParcelPrivilege(Privilege.ADMIN)
+ fun ParcelScope.cmdReset(context: ExecutionContext, @Flag sure: Boolean): Any? {
+ Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
+ if (!sure) return areYouSureMessage(context)
+
+ parcel.dispose()
+ world.blockManager.clearParcel(parcel.id)?.reportProgressUpdates(context, "Reset")
+ return "Data of (${parcel.id.idString}) has been disposed"
+ }
+
+ @Cmd("swap")
+ @RequireParcelPrivilege(Privilege.ADMIN)
+ fun ParcelScope.cmdSwap(
+ context: ExecutionContext,
+ @TargetKind(TargetKind.ID) target: ParcelTarget,
+ @Flag sure: Boolean
+ ): Any? {
+ Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
+ if (!sure) return areYouSureMessage(context)
+
+ val parcel2 = (target as ParcelTarget.ByID).getParcel()
+ ?: throw CommandException("Invalid parcel target")
+
+ // Validate.isTrue(parcel2.world == world, "Parcel must be in the same world")
+ Validate.isTrue(!parcel2.hasBlockVisitors, "A process is already running in that parcel")
+
+ val data = parcel.data
+ parcel.copyData(parcel2.data)
+ parcel2.copyData(data)
+
+ val job = plugin.parcelProvider.swapParcels(parcel.id, parcel2.id)?.reportProgressUpdates(context, "Swap")
+ Validate.notNull(job, "A process is already running in some parcel (internal error)")
+ return null
+ }
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
index cee3e62..a2bd8d1 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
@@ -1,132 +1,132 @@
-@file:Suppress("NON_EXHAUSTIVE_WHEN")
-
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.Validate
-import io.dico.dicore.command.annotation.Cmd
-import io.dico.dicore.command.annotation.Desc
-import io.dico.parcels2.*
-import io.dico.parcels2.Privilege.BANNED
-import io.dico.parcels2.Privilege.CAN_BUILD
-import io.dico.parcels2.PrivilegeChangeResult.*
-import io.dico.parcels2.defaultimpl.InfoBuilder
-import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
-import org.bukkit.OfflinePlayer
-
-class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
- private val data
- inline get() = plugin.globalPrivileges
-
- private fun checkContext(context: ExecutionContext, owner: OfflinePlayer, changing: Boolean = true): OfflinePlayer {
- if (changing) {
- checkConnected("have privileges changed")
- }
- val sender = context.sender
- if (sender !== owner) {
- Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
- }
- return owner
- }
-
- @Cmd("list", aliases = ["l"])
- @Desc(
- "List globally declared privileges, players you",
- "allowed to build on or banned from all your parcels",
- shortVersion = "lists globally declared privileges"
- )
- fun cmdList(context: ExecutionContext, owner: OfflinePlayer): Any? {
- checkContext(context, owner, changing = false)
- val map = plugin.globalPrivileges[owner]
- Validate.isTrue(map.hasAnyDeclaredPrivileges(), "This user has not declared any global privileges")
-
- return StringBuilder().apply {
- with(InfoBuilder) {
- appendProfilesWithPrivilege("Globally Allowed", map, null, CAN_BUILD)
- appendProfilesWithPrivilege("Globally Banned", map, null, BANNED)
- }
- }.toString()
- }
-
- @Cmd("entrust")
- @Desc(
- "Allows a player to manage globally",
- shortVersion = "allows a player to manage globally"
- )
- suspend fun cmdEntrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].allowManage(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is already allowed to manage globally")
- SUCCESS -> "${player.name} is now allowed to manage globally"
- }
-
- @Cmd("distrust")
- @Desc(
- "Disallows a player to manage globally,",
- "they will still be able to build",
- shortVersion = "disallows a player to manage globally"
- )
- suspend fun cmdDistrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].disallowManage(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is not currently allowed to manage globally")
- SUCCESS -> "${player.name} is not allowed to manage globally anymore"
- }
-
- @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"
- )
- suspend fun cmdAllow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].allowBuild(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is already allowed globally")
- SUCCESS -> "${player.name} is now allowed to build globally"
- }
-
- @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"
- )
- suspend fun cmdDisallow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].disallowBuild(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is not currently allowed globally")
- SUCCESS -> "${player.name} is not allowed to build globally 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"
- )
- suspend fun cmdBan(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].disallowEnter(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is already banned globally")
- SUCCESS -> "${player.name} is now banned globally"
- }
-
- @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"
- )
- suspend fun cmdUnban(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
- when (data[checkContext(context, owner)].allowEnter(toPrivilegeKey(player))) {
- FAIL_OWNER -> err("The target cannot be the owner themselves")
- FAIL -> err("${player.name} is not currently banned globally")
- SUCCESS -> "${player.name} is not banned globally anymore"
- }
-
+@file:Suppress("NON_EXHAUSTIVE_WHEN")
+
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.Validate
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.Desc
+import io.dico.parcels2.*
+import io.dico.parcels2.Privilege.BANNED
+import io.dico.parcels2.Privilege.CAN_BUILD
+import io.dico.parcels2.PrivilegeChangeResult.*
+import io.dico.parcels2.defaultimpl.InfoBuilder
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
+import org.bukkit.OfflinePlayer
+
+class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
+ private val data
+ inline get() = plugin.globalPrivileges
+
+ private fun checkContext(context: ExecutionContext, owner: OfflinePlayer, changing: Boolean = true): OfflinePlayer {
+ if (changing) {
+ checkConnected("have privileges changed")
+ }
+ val sender = context.sender
+ if (sender !== owner) {
+ Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
+ }
+ return owner
+ }
+
+ @Cmd("list", aliases = ["l"])
+ @Desc(
+ "List globally declared privileges, players you",
+ "allowed to build on or banned from all your parcels",
+ shortVersion = "lists globally declared privileges"
+ )
+ fun cmdList(context: ExecutionContext, owner: OfflinePlayer): Any? {
+ checkContext(context, owner, changing = false)
+ val map = plugin.globalPrivileges[owner]
+ Validate.isTrue(map.hasAnyDeclaredPrivileges(), "This user has not declared any global privileges")
+
+ return StringBuilder().apply {
+ with(InfoBuilder) {
+ appendProfilesWithPrivilege("Globally Allowed", map, null, CAN_BUILD)
+ appendProfilesWithPrivilege("Globally Banned", map, null, BANNED)
+ }
+ }.toString()
+ }
+
+ @Cmd("entrust")
+ @Desc(
+ "Allows a player to manage globally",
+ shortVersion = "allows a player to manage globally"
+ )
+ suspend fun cmdEntrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowManage(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already allowed to manage globally")
+ SUCCESS -> "${player.name} is now allowed to manage globally"
+ }
+
+ @Cmd("distrust")
+ @Desc(
+ "Disallows a player to manage globally,",
+ "they will still be able to build",
+ shortVersion = "disallows a player to manage globally"
+ )
+ suspend fun cmdDistrust(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowManage(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently allowed to manage globally")
+ SUCCESS -> "${player.name} is not allowed to manage globally anymore"
+ }
+
+ @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"
+ )
+ suspend fun cmdAllow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowBuild(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already allowed globally")
+ SUCCESS -> "${player.name} is now allowed to build globally"
+ }
+
+ @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"
+ )
+ suspend fun cmdDisallow(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowBuild(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently allowed globally")
+ SUCCESS -> "${player.name} is not allowed to build globally 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"
+ )
+ suspend fun cmdBan(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].disallowEnter(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is already banned globally")
+ SUCCESS -> "${player.name} is now banned globally"
+ }
+
+ @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"
+ )
+ suspend fun cmdUnban(context: ExecutionContext, owner: OfflinePlayer, player: PlayerProfile): Any? =
+ when (data[checkContext(context, owner)].allowEnter(toPrivilegeKey(player))) {
+ FAIL_OWNER -> err("The target cannot be the owner themselves")
+ FAIL -> err("${player.name} is not currently banned globally")
+ SUCCESS -> "${player.name} is not banned globally anymore"
+ }
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
index e0bde7d..3f166ad 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
@@ -1,162 +1,162 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.Formatting
-import io.dico.dicore.command.*
-import io.dico.dicore.command.IContextFilter.Priority.PERMISSION
-import io.dico.dicore.command.annotation.Cmd
-import io.dico.dicore.command.annotation.PreprocessArgs
-import io.dico.dicore.command.annotation.RequireParameters
-import io.dico.dicore.command.parameter.ArgumentBuffer
-import io.dico.parcels2.*
-import io.dico.parcels2.blockvisitor.RegionTraverser
-import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
-import io.dico.parcels2.util.ext.PERM_BAN_BYPASS
-import io.dico.parcels2.util.ext.PERM_BUILD_ANYWHERE
-import kotlinx.coroutines.launch
-import org.bukkit.Bukkit
-import org.bukkit.Material
-import org.bukkit.block.BlockFace
-import org.bukkit.block.data.Directional
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
-import java.util.Random
-
-class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
-
- @Cmd("reloadoptions")
- fun reloadOptions() {
- plugin.loadOptions()
- }
-
- @Cmd("tpworld")
- fun tpWorld(sender: Player, worldName: String): String {
- if (worldName == "list") {
- return Bukkit.getWorlds().joinToString("\n- ", "- ", "")
- }
- val world = Bukkit.getWorld(worldName) ?: err("World $worldName is not loaded")
- sender.teleport(world.spawnLocation)
- return "Teleported you to $worldName spawn"
- }
-
- @Cmd("make_mess")
- @RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdMakeMess(context: ExecutionContext) {
- Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
-
- val server = plugin.server
- val blockDatas = arrayOf(
- server.createBlockData(Material.BLUE_WOOL),
- server.createBlockData(Material.LIME_WOOL),
- server.createBlockData(Material.GLASS),
- server.createBlockData(Material.STONE_SLAB),
- server.createBlockData(Material.STONE),
- server.createBlockData(Material.QUARTZ_BLOCK),
- server.createBlockData(Material.BROWN_CONCRETE)
- )
- val random = Random()
-
- world.blockManager.tryDoBlockOperation(plugin.parcelProvider, parcel.id, traverser = RegionTraverser.upward) { block ->
- block.blockData = blockDatas[random.nextInt(7)]
- }?.onProgressUpdate(1000, 1000) { progress, elapsedTime ->
- context.sendMessage(
- EMessageType.INFORMATIVE, "Mess progress: %.02f%%, %.2fs elapsed"
- .format(progress * 100, elapsedTime / 1000.0)
- )
- }
- }
-
- @Cmd("directionality", aliases = ["dir"])
- fun cmdDirectionality(sender: Player, context: ExecutionContext, material: Material): Any? {
- val senderLoc = sender.location
- val block = senderLoc.add(senderLoc.direction.setY(0).normalize().multiply(2).toLocation(sender.world)).block
-
- val blockData = Bukkit.createBlockData(material)
- if (blockData is Directional) {
- blockData.facing = BlockFace.SOUTH
- }
-
- block.blockData = blockData
- return if (blockData is Directional) "The block is facing south" else "The block is not directional, however it implements " +
- blockData.javaClass.interfaces!!.contentToString()
- }
-
- @Cmd("jobs")
- fun cmdJobs(): Any? {
- val workers = plugin.jobDispatcher.jobs
- println(workers.map { it.coroutine }.joinToString(separator = "\n"))
- return "Task count: ${workers.size}"
- }
-
- @Cmd("complete_jobs")
- fun cmdCompleteJobs(): Any? = cmdJobs().also {
- plugin.launch { plugin.jobDispatcher.completeAllTasks() }
- }
-
- @Cmd("message")
- @PreprocessArgs
- fun cmdMessage(sender: CommandSender, message: String): Any? {
- // testing @PreprocessArgs which merges "hello there" into a single argument
- sender.sendMessage(Formatting.translate(message))
- return null
- }
-
- @Cmd("hasperm")
- fun cmdHasperm(target: Player, permission: String): Any? {
- return target.hasPermission(permission).toString()
- }
-
- @Cmd("permissions")
- fun cmdPermissions(context: ExecutionContext, of: Player, vararg address: String): Any? {
- val target = context.address.dispatcherForTree.getDeepChild(ArgumentBuffer(address))
- Validate.isTrue(target.depth == address.size && target.hasCommand(), "Not found: /${address.joinToString(separator = " ")}")
- return getPermissionsOf(target).joinToString(separator = "\n") { "$it: ${of.hasPermission(it)}" }
- }
-
- @Cmd("privilege")
- @RequireParameters(1)
- suspend fun ParcelScope.cmdPrivilege(target: PlayerProfile, adminPerm: String?): Any? {
- val key = toPrivilegeKey(target)
-
- val perm = when (adminPerm) {
- "none" -> null
- "build" -> PERM_BUILD_ANYWHERE
- "manage", null -> PERM_ADMIN_MANAGE
- "enter" -> PERM_BAN_BYPASS
- else -> err("adminPerm should be build, manager or enter")
- }
-
- val privilege = if (perm == null) {
- parcel.getStoredPrivilege(key)
- } else {
- if (key is PlayerProfile.Star) err("* can't have permissions")
- parcel.getEffectivePrivilege(key.player!!, perm)
- }
-
- return privilege.toString()
- }
-
- private fun getPermissionsOf(address: ICommandAddress) = getPermissionsOf(address, emptyArray(), mutableListOf())
-
- private fun getPermissionsOf(address: ICommandAddress, path: Array<String>, result: MutableList<String>): List<String> {
- val command = address.command ?: return result
-
- var inherited = false
- for (filter in command.contextFilters) {
- when (filter) {
- is PermissionContextFilter -> {
- if (path.isEmpty()) result.add(filter.permission)
- else if (filter.isInheritable) result.add(filter.getInheritedPermission(path))
- }
- is InheritingContextFilter -> {
- if (filter.priority == PERMISSION && address.hasParent() && !inherited) {
- inherited = true
- getPermissionsOf(address.parent, arrayOf(address.mainKey, *path), result)
- }
- }
- }
- }
-
- return result
- }
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.Formatting
+import io.dico.dicore.command.*
+import io.dico.dicore.command.IContextFilter.Priority.PERMISSION
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.PreprocessArgs
+import io.dico.dicore.command.annotation.RequireParameters
+import io.dico.dicore.command.parameter.ArgumentBuffer
+import io.dico.parcels2.*
+import io.dico.parcels2.blockvisitor.RegionTraverser
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
+import io.dico.parcels2.util.ext.PERM_BAN_BYPASS
+import io.dico.parcels2.util.ext.PERM_BUILD_ANYWHERE
+import kotlinx.coroutines.launch
+import org.bukkit.Bukkit
+import org.bukkit.Material
+import org.bukkit.block.BlockFace
+import org.bukkit.block.data.Directional
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+import java.util.Random
+
+class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
+
+ @Cmd("reloadoptions")
+ fun reloadOptions() {
+ plugin.loadOptions()
+ }
+
+ @Cmd("tpworld")
+ fun tpWorld(sender: Player, worldName: String): String {
+ if (worldName == "list") {
+ return Bukkit.getWorlds().joinToString("\n- ", "- ", "")
+ }
+ val world = Bukkit.getWorld(worldName) ?: err("World $worldName is not loaded")
+ sender.teleport(world.spawnLocation)
+ return "Teleported you to $worldName spawn"
+ }
+
+ @Cmd("make_mess")
+ @RequireParcelPrivilege(Privilege.OWNER)
+ fun ParcelScope.cmdMakeMess(context: ExecutionContext) {
+ Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
+
+ val server = plugin.server
+ val blockDatas = arrayOf(
+ server.createBlockData(Material.BLUE_WOOL),
+ server.createBlockData(Material.LIME_WOOL),
+ server.createBlockData(Material.GLASS),
+ server.createBlockData(Material.STONE_SLAB),
+ server.createBlockData(Material.STONE),
+ server.createBlockData(Material.QUARTZ_BLOCK),
+ server.createBlockData(Material.BROWN_CONCRETE)
+ )
+ val random = Random()
+
+ world.blockManager.tryDoBlockOperation(plugin.parcelProvider, parcel.id, traverser = RegionTraverser.upward) { block ->
+ block.blockData = blockDatas[random.nextInt(7)]
+ }?.onProgressUpdate(1000, 1000) { progress, elapsedTime ->
+ context.sendMessage(
+ EMessageType.INFORMATIVE, "Mess progress: %.02f%%, %.2fs elapsed"
+ .format(progress * 100, elapsedTime / 1000.0)
+ )
+ }
+ }
+
+ @Cmd("directionality", aliases = ["dir"])
+ fun cmdDirectionality(sender: Player, context: ExecutionContext, material: Material): Any? {
+ val senderLoc = sender.location
+ val block = senderLoc.add(senderLoc.direction.setY(0).normalize().multiply(2).toLocation(sender.world)).block
+
+ val blockData = Bukkit.createBlockData(material)
+ if (blockData is Directional) {
+ blockData.facing = BlockFace.SOUTH
+ }
+
+ block.blockData = blockData
+ return if (blockData is Directional) "The block is facing south" else "The block is not directional, however it implements " +
+ blockData.javaClass.interfaces!!.contentToString()
+ }
+
+ @Cmd("jobs")
+ fun cmdJobs(): Any? {
+ val workers = plugin.jobDispatcher.jobs
+ println(workers.map { it.coroutine }.joinToString(separator = "\n"))
+ return "Task count: ${workers.size}"
+ }
+
+ @Cmd("complete_jobs")
+ fun cmdCompleteJobs(): Any? = cmdJobs().also {
+ plugin.launch { plugin.jobDispatcher.completeAllTasks() }
+ }
+
+ @Cmd("message")
+ @PreprocessArgs
+ fun cmdMessage(sender: CommandSender, message: String): Any? {
+ // testing @PreprocessArgs which merges "hello there" into a single argument
+ sender.sendMessage(Formatting.translate(message))
+ return null
+ }
+
+ @Cmd("hasperm")
+ fun cmdHasperm(target: Player, permission: String): Any? {
+ return target.hasPermission(permission).toString()
+ }
+
+ @Cmd("permissions")
+ fun cmdPermissions(context: ExecutionContext, of: Player, vararg address: String): Any? {
+ val target = context.address.dispatcherForTree.getDeepChild(ArgumentBuffer(address))
+ Validate.isTrue(target.depth == address.size && target.hasCommand(), "Not found: /${address.joinToString(separator = " ")}")
+ return getPermissionsOf(target).joinToString(separator = "\n") { "$it: ${of.hasPermission(it)}" }
+ }
+
+ @Cmd("privilege")
+ @RequireParameters(1)
+ suspend fun ParcelScope.cmdPrivilege(target: PlayerProfile, adminPerm: String?): Any? {
+ val key = toPrivilegeKey(target)
+
+ val perm = when (adminPerm) {
+ "none" -> null
+ "build" -> PERM_BUILD_ANYWHERE
+ "manage", null -> PERM_ADMIN_MANAGE
+ "enter" -> PERM_BAN_BYPASS
+ else -> err("adminPerm should be build, manager or enter")
+ }
+
+ val privilege = if (perm == null) {
+ parcel.getStoredPrivilege(key)
+ } else {
+ if (key is PlayerProfile.Star) err("* can't have permissions")
+ parcel.getEffectivePrivilege(key.player!!, perm)
+ }
+
+ return privilege.toString()
+ }
+
+ private fun getPermissionsOf(address: ICommandAddress) = getPermissionsOf(address, emptyArray(), mutableListOf())
+
+ private fun getPermissionsOf(address: ICommandAddress, path: Array<String>, result: MutableList<String>): List<String> {
+ val command = address.command ?: return result
+
+ var inherited = false
+ for (filter in command.contextFilters) {
+ when (filter) {
+ is PermissionContextFilter -> {
+ if (path.isEmpty()) result.add(filter.permission)
+ else if (filter.isInheritable) result.add(filter.getInheritedPermission(path))
+ }
+ is InheritingContextFilter -> {
+ if (filter.priority == PERMISSION && address.hasParent() && !inherited) {
+ inherited = true
+ getPermissionsOf(address.parent, arrayOf(address.mainKey, *path), result)
+ }
+ }
+ }
+ }
+
+ return result
+ }
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
index c918b80..61e8d9e 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
@@ -1,142 +1,142 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.Validate
-import io.dico.dicore.command.annotation.Cmd
-import io.dico.dicore.command.annotation.Desc
-import io.dico.dicore.command.annotation.Flag
-import io.dico.dicore.command.annotation.RequireParameters
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.PlayerProfile
-import io.dico.parcels2.Privilege
-import io.dico.parcels2.command.ParcelTarget.TargetKind
-import io.dico.parcels2.util.ext.hasParcelHomeOthers
-import io.dico.parcels2.util.ext.hasPermAdminManage
-import io.dico.parcels2.util.ext.uuid
-import org.bukkit.block.Biome
-import org.bukkit.entity.Player
-
-class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : AbstractParcelCommands(plugin) {
-
- @Cmd("auto")
- @Desc(
- "Finds the unclaimed parcel nearest to origin,",
- "and gives it to you",
- shortVersion = "sets you up with a fresh, unclaimed parcel"
- )
- suspend fun WorldScope.cmdAuto(player: Player): Any? {
- checkConnected("be claimed")
- checkParcelLimit(player, world)
-
- val parcel = world.nextEmptyParcel()
- ?: err("This world is full, please ask an admin to upsize it")
- parcel.owner = PlayerProfile(uuid = player.uuid)
- player.teleport(parcel.homeLocation)
- return "Enjoy your new parcel!"
- }
-
- @Cmd("info", aliases = ["i"])
- @Desc(
- "Displays general information",
- "about the parcel you're on",
- shortVersion = "displays information about this parcel"
- )
- fun ParcelScope.cmdInfo(player: Player) = parcel.infoString
-
- init {
- parent.addSpeciallyTreatedKeys("home", "h")
- }
-
- @Cmd("home", aliases = ["h"])
- @Desc(
- "Teleports you to your parcels,",
- "unless another player was specified.",
- "You can specify an index number if you have",
- "more than one parcel",
- shortVersion = "teleports you to parcels"
- )
- @RequireParameters(0)
- suspend fun cmdHome(
- player: Player,
- @TargetKind(TargetKind.OWNER_REAL) target: ParcelTarget
- ): Any? {
- return cmdGoto(player, target)
- }
-
- @Cmd("tp", aliases = ["teleport"])
- suspend fun cmdTp(
- player: Player,
- @TargetKind(TargetKind.ID) target: ParcelTarget
- ): Any? {
- return cmdGoto(player, target)
- }
-
- @Cmd("goto")
- suspend fun cmdGoto(
- player: Player,
- @TargetKind(TargetKind.ANY) target: ParcelTarget
- ): Any? {
- if (target is ParcelTarget.ByOwner) {
- target.resolveOwner(plugin.storage)
- if (!target.owner.matches(player) && !player.hasParcelHomeOthers) {
- err("You do not have permission to teleport to other people's parcels")
- }
- }
-
- val match = target.getParcelSuspend(plugin.storage)
- ?: err("The specified parcel could not be matched")
- player.teleport(match.homeLocation)
- return null
- }
-
- @Cmd("goto_fake")
- suspend fun cmdGotoFake(
- player: Player,
- @TargetKind(TargetKind.OWNER_FAKE) target: ParcelTarget
- ): Any? {
- return cmdGoto(player, target)
- }
-
- @Cmd("claim")
- @Desc(
- "If this parcel is unowned, makes you the owner",
- shortVersion = "claims this parcel"
- )
- suspend fun ParcelScope.cmdClaim(player: Player): Any? {
- checkConnected("be claimed")
- parcel.owner.takeIf { !player.hasPermAdminManage }?.let {
- err(if (it.matches(player)) "You already own this parcel" else "This parcel is not available")
- }
-
- checkParcelLimit(player, world)
- parcel.owner = PlayerProfile(player)
- return "Enjoy your new parcel!"
- }
-
- @Cmd("unclaim")
- @Desc("Unclaims this parcel")
- @RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdUnclaim(player: Player): Any? {
- checkConnected("be unclaimed")
- parcel.dispose()
- return "Your parcel has been disposed"
- }
-
- @Cmd("clear")
- @RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdClear(context: ExecutionContext, @Flag sure: Boolean): Any? {
- Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
- if (!sure) return areYouSureMessage(context)
- world.blockManager.clearParcel(parcel.id)?.reportProgressUpdates(context, "Clear")
- return null
- }
-
- @Cmd("setbiome")
- @RequireParcelPrivilege(Privilege.OWNER)
- fun ParcelScope.cmdSetbiome(context: ExecutionContext, biome: Biome): Any? {
- Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
- world.blockManager.setBiome(parcel.id, biome)?.reportProgressUpdates(context, "Biome change")
- return null
- }
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.Validate
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.Desc
+import io.dico.dicore.command.annotation.Flag
+import io.dico.dicore.command.annotation.RequireParameters
+import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.PlayerProfile
+import io.dico.parcels2.Privilege
+import io.dico.parcels2.command.ParcelTarget.TargetKind
+import io.dico.parcels2.util.ext.hasParcelHomeOthers
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import io.dico.parcels2.util.ext.uuid
+import org.bukkit.block.Biome
+import org.bukkit.entity.Player
+
+class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : AbstractParcelCommands(plugin) {
+
+ @Cmd("auto")
+ @Desc(
+ "Finds the unclaimed parcel nearest to origin,",
+ "and gives it to you",
+ shortVersion = "sets you up with a fresh, unclaimed parcel"
+ )
+ suspend fun WorldScope.cmdAuto(player: Player): Any? {
+ checkConnected("be claimed")
+ checkParcelLimit(player, world)
+
+ val parcel = world.nextEmptyParcel()
+ ?: err("This world is full, please ask an admin to upsize it")
+ parcel.owner = PlayerProfile(uuid = player.uuid)
+ player.teleport(parcel.homeLocation)
+ return "Enjoy your new parcel!"
+ }
+
+ @Cmd("info", aliases = ["i"])
+ @Desc(
+ "Displays general information",
+ "about the parcel you're on",
+ shortVersion = "displays information about this parcel"
+ )
+ fun ParcelScope.cmdInfo(player: Player) = parcel.infoString
+
+ init {
+ parent.addSpeciallyTreatedKeys("home", "h")
+ }
+
+ @Cmd("home", aliases = ["h"])
+ @Desc(
+ "Teleports you to your parcels,",
+ "unless another player was specified.",
+ "You can specify an index number if you have",
+ "more than one parcel",
+ shortVersion = "teleports you to parcels"
+ )
+ @RequireParameters(0)
+ suspend fun cmdHome(
+ player: Player,
+ @TargetKind(TargetKind.OWNER_REAL) target: ParcelTarget
+ ): Any? {
+ return cmdGoto(player, target)
+ }
+
+ @Cmd("tp", aliases = ["teleport"])
+ suspend fun cmdTp(
+ player: Player,
+ @TargetKind(TargetKind.ID) target: ParcelTarget
+ ): Any? {
+ return cmdGoto(player, target)
+ }
+
+ @Cmd("goto")
+ suspend fun cmdGoto(
+ player: Player,
+ @TargetKind(TargetKind.ANY) target: ParcelTarget
+ ): Any? {
+ if (target is ParcelTarget.ByOwner) {
+ target.resolveOwner(plugin.storage)
+ if (!target.owner.matches(player) && !player.hasParcelHomeOthers) {
+ err("You do not have permission to teleport to other people's parcels")
+ }
+ }
+
+ val match = target.getParcelSuspend(plugin.storage)
+ ?: err("The specified parcel could not be matched")
+ player.teleport(match.homeLocation)
+ return null
+ }
+
+ @Cmd("goto_fake")
+ suspend fun cmdGotoFake(
+ player: Player,
+ @TargetKind(TargetKind.OWNER_FAKE) target: ParcelTarget
+ ): Any? {
+ return cmdGoto(player, target)
+ }
+
+ @Cmd("claim")
+ @Desc(
+ "If this parcel is unowned, makes you the owner",
+ shortVersion = "claims this parcel"
+ )
+ suspend fun ParcelScope.cmdClaim(player: Player): Any? {
+ checkConnected("be claimed")
+ parcel.owner.takeIf { !player.hasPermAdminManage }?.let {
+ err(if (it.matches(player)) "You already own this parcel" else "This parcel is not available")
+ }
+
+ checkParcelLimit(player, world)
+ parcel.owner = PlayerProfile(player)
+ return "Enjoy your new parcel!"
+ }
+
+ @Cmd("unclaim")
+ @Desc("Unclaims this parcel")
+ @RequireParcelPrivilege(Privilege.OWNER)
+ fun ParcelScope.cmdUnclaim(player: Player): Any? {
+ checkConnected("be unclaimed")
+ parcel.dispose()
+ return "Your parcel has been disposed"
+ }
+
+ @Cmd("clear")
+ @RequireParcelPrivilege(Privilege.OWNER)
+ fun ParcelScope.cmdClear(context: ExecutionContext, @Flag sure: Boolean): Any? {
+ Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
+ if (!sure) return areYouSureMessage(context)
+ world.blockManager.clearParcel(parcel.id)?.reportProgressUpdates(context, "Clear")
+ return null
+ }
+
+ @Cmd("setbiome")
+ @RequireParcelPrivilege(Privilege.OWNER)
+ fun ParcelScope.cmdSetbiome(context: ExecutionContext, biome: Biome): Any? {
+ Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
+ world.blockManager.setBiome(parcel.id, biome)?.reportProgressUpdates(context, "Biome change")
+ return null
+ }
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
index 3b4234c..33ffb8b 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt
@@ -1,77 +1,77 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.annotation.Cmd
-import io.dico.dicore.command.annotation.Desc
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.PlayerProfile
-import org.bukkit.entity.Player
-
-class CommandsPrivilegesGlobal(plugin: ParcelsPlugin,
- val adminVersion: CommandsAdminPrivilegesGlobal) : AbstractParcelCommands(plugin) {
- @Cmd("list", aliases = ["l"])
- @Desc(
- "List globally declared privileges, players you",
- "allowed to build on or banned from all your parcels",
- shortVersion = "lists globally declared privileges"
- )
- fun cmdList(sender: Player, context: ExecutionContext) =
- adminVersion.cmdList(context, sender)
-
- @Cmd("entrust")
- @Desc(
- "Allows a player to manage globally",
- shortVersion = "allows a player to manage globally"
- )
- suspend fun cmdEntrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdEntrust(context, sender, player)
-
- @Cmd("distrust")
- @Desc(
- "Disallows a player to manage globally,",
- "they will still be able to build",
- shortVersion = "disallows a player to manage globally"
- )
- suspend fun cmdDistrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdDistrust(context, sender, 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"
- )
- suspend fun cmdAllow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdAllow(context, sender, player)
-
- @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"
- )
- suspend fun cmdDisallow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdDisallow(context, sender, player)
-
- @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"
- )
- suspend fun cmdBan(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdBan(context, sender, player)
-
- @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"
- )
- suspend fun cmdUnban(sender: Player, context: ExecutionContext, player: PlayerProfile) =
- adminVersion.cmdUnban(context, sender, player)
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.annotation.Cmd
+import io.dico.dicore.command.annotation.Desc
+import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.PlayerProfile
+import org.bukkit.entity.Player
+
+class CommandsPrivilegesGlobal(plugin: ParcelsPlugin,
+ val adminVersion: CommandsAdminPrivilegesGlobal) : AbstractParcelCommands(plugin) {
+ @Cmd("list", aliases = ["l"])
+ @Desc(
+ "List globally declared privileges, players you",
+ "allowed to build on or banned from all your parcels",
+ shortVersion = "lists globally declared privileges"
+ )
+ fun cmdList(sender: Player, context: ExecutionContext) =
+ adminVersion.cmdList(context, sender)
+
+ @Cmd("entrust")
+ @Desc(
+ "Allows a player to manage globally",
+ shortVersion = "allows a player to manage globally"
+ )
+ suspend fun cmdEntrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdEntrust(context, sender, player)
+
+ @Cmd("distrust")
+ @Desc(
+ "Disallows a player to manage globally,",
+ "they will still be able to build",
+ shortVersion = "disallows a player to manage globally"
+ )
+ suspend fun cmdDistrust(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdDistrust(context, sender, 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"
+ )
+ suspend fun cmdAllow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdAllow(context, sender, player)
+
+ @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"
+ )
+ suspend fun cmdDisallow(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdDisallow(context, sender, player)
+
+ @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"
+ )
+ suspend fun cmdBan(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdBan(context, sender, player)
+
+ @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"
+ )
+ suspend fun cmdUnban(sender: Player, context: ExecutionContext, player: PlayerProfile) =
+ adminVersion.cmdUnban(context, sender, player)
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
index 21910b1..e3aba22 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
@@ -1,144 +1,144 @@
-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.*
-import io.dico.parcels2.PrivilegeChangeResult.*
-import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
-import io.dico.parcels2.util.ext.hasPermAdminManage
-import org.bukkit.entity.Player
-
-class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
-
- private fun ParcelScope.checkPrivilege(sender: Player, key: PrivilegeKey) {
- val senderPrivilege = parcel.getEffectivePrivilege(sender, PERM_ADMIN_MANAGE)
- val targetPrivilege = parcel.getStoredPrivilege(key)
- Validate.isTrue(senderPrivilege > targetPrivilege, "You may not change the privilege of ${key.notNullName}")
- }
-
- private fun ParcelScope.checkOwned(sender: Player) {
- Validate.isTrue(parcel.owner != null || sender.hasPermAdminManage, "This parcel is unowned")
- }
-
- @Cmd("entrust")
- @Desc(
- "Allows a player to manage this parcel",
- shortVersion = "allows a player to manage this parcel"
- )
- @RequireParcelPrivilege(Privilege.OWNER)
- suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- return when (parcel.allowManage(key)) {
- FAIL_OWNER -> err("The target already owns the parcel")
- FAIL -> err("${player.name} is already allowed to manage this parcel")
- SUCCESS -> "${player.name} is now allowed to manage this parcel"
- }
- }
-
- @Cmd("distrust")
- @Desc(
- "Disallows a player to manage this parcel,",
- "they will still be able to build",
- shortVersion = "disallows a player to manage this parcel"
- )
- @RequireParcelPrivilege(Privilege.OWNER)
- suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- return when (parcel.disallowManage(key)) {
- FAIL_OWNER -> err("The target owns the parcel and can't be distrusted")
- FAIL -> err("${player.name} is not currently allowed to manage this parcel")
- SUCCESS -> "${player.name} is not allowed to manage this parcel anymore"
- }
- }
-
- @Cmd("allow", aliases = ["add", "permit"])
- @Desc(
- "Allows a player to build on this parcel",
- shortVersion = "allows a player to build on this parcel"
- )
- @RequireParcelPrivilege(Privilege.CAN_MANAGE)
- suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- checkPrivilege(sender, key)
-
- return when (parcel.allowBuild(key)) {
- FAIL_OWNER -> err("The target already owns the parcel")
- FAIL -> err("${player.name} is already allowed to build on this parcel")
- SUCCESS -> "${player.name} is now allowed to build on this parcel"
- }
- }
-
- @Cmd("disallow", aliases = ["remove", "forbid"])
- @Desc(
- "Disallows a player to build on this parcel,",
- "they won't be allowed to anymore",
- shortVersion = "disallows a player to build on this parcel"
- )
- @RequireParcelPrivilege(Privilege.CAN_MANAGE)
- suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- checkPrivilege(sender, key)
-
- return when (parcel.disallowBuild(key)) {
- FAIL_OWNER -> err("The target owns the parcel")
- FAIL -> err("${player.name} is not currently allowed to build on this parcel")
- SUCCESS -> "${player.name} is not allowed to build on this parcel anymore"
- }
- }
-
- @Cmd("ban", aliases = ["deny"])
- @Desc(
- "Bans a player from this parcel,",
- "making them unable to enter",
- shortVersion = "bans a player from this parcel"
- )
- @RequireParcelPrivilege(Privilege.CAN_MANAGE)
- suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- checkPrivilege(sender, key)
-
- return when (parcel.disallowEnter(key)) {
- FAIL_OWNER -> err("The target owns the parcel")
- FAIL -> err("${player.name} is already banned from this parcel")
- SUCCESS -> "${player.name} is now banned from this parcel"
- }
- }
-
- @Cmd("unban", aliases = ["undeny"])
- @Desc(
- "Unbans a player from this parcel,",
- "they will be able to enter it again",
- shortVersion = "unbans a player from this parcel"
- )
- @RequireParcelPrivilege(Privilege.CAN_MANAGE)
- suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
- checkConnected("have privileges changed")
- checkOwned(sender)
-
- val key = toPrivilegeKey(player)
- checkPrivilege(sender, key)
-
- return when (parcel.allowEnter(key)) {
- FAIL_OWNER -> err("The target owns the parcel")
- FAIL -> err("${player.name} is not currently banned from this parcel")
- SUCCESS -> "${player.name} is not banned from this parcel anymore"
- }
- }
-
+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.*
+import io.dico.parcels2.PrivilegeChangeResult.*
+import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import org.bukkit.entity.Player
+
+class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
+
+ private fun ParcelScope.checkPrivilege(sender: Player, key: PrivilegeKey) {
+ val senderPrivilege = parcel.getEffectivePrivilege(sender, PERM_ADMIN_MANAGE)
+ val targetPrivilege = parcel.getStoredPrivilege(key)
+ Validate.isTrue(senderPrivilege > targetPrivilege, "You may not change the privilege of ${key.notNullName}")
+ }
+
+ private fun ParcelScope.checkOwned(sender: Player) {
+ Validate.isTrue(parcel.owner != null || sender.hasPermAdminManage, "This parcel is unowned")
+ }
+
+ @Cmd("entrust")
+ @Desc(
+ "Allows a player to manage this parcel",
+ shortVersion = "allows a player to manage this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.OWNER)
+ suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ return when (parcel.allowManage(key)) {
+ FAIL_OWNER -> err("The target already owns the parcel")
+ FAIL -> err("${player.name} is already allowed to manage this parcel")
+ SUCCESS -> "${player.name} is now allowed to manage this parcel"
+ }
+ }
+
+ @Cmd("distrust")
+ @Desc(
+ "Disallows a player to manage this parcel,",
+ "they will still be able to build",
+ shortVersion = "disallows a player to manage this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.OWNER)
+ suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ return when (parcel.disallowManage(key)) {
+ FAIL_OWNER -> err("The target owns the parcel and can't be distrusted")
+ FAIL -> err("${player.name} is not currently allowed to manage this parcel")
+ SUCCESS -> "${player.name} is not allowed to manage this parcel anymore"
+ }
+ }
+
+ @Cmd("allow", aliases = ["add", "permit"])
+ @Desc(
+ "Allows a player to build on this parcel",
+ shortVersion = "allows a player to build on this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.CAN_MANAGE)
+ suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
+
+ return when (parcel.allowBuild(key)) {
+ FAIL_OWNER -> err("The target already owns the parcel")
+ FAIL -> err("${player.name} is already allowed to build on this parcel")
+ SUCCESS -> "${player.name} is now allowed to build on this parcel"
+ }
+ }
+
+ @Cmd("disallow", aliases = ["remove", "forbid"])
+ @Desc(
+ "Disallows a player to build on this parcel,",
+ "they won't be allowed to anymore",
+ shortVersion = "disallows a player to build on this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.CAN_MANAGE)
+ suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
+
+ return when (parcel.disallowBuild(key)) {
+ FAIL_OWNER -> err("The target owns the parcel")
+ FAIL -> err("${player.name} is not currently allowed to build on this parcel")
+ SUCCESS -> "${player.name} is not allowed to build on this parcel anymore"
+ }
+ }
+
+ @Cmd("ban", aliases = ["deny"])
+ @Desc(
+ "Bans a player from this parcel,",
+ "making them unable to enter",
+ shortVersion = "bans a player from this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.CAN_MANAGE)
+ suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
+
+ return when (parcel.disallowEnter(key)) {
+ FAIL_OWNER -> err("The target owns the parcel")
+ FAIL -> err("${player.name} is already banned from this parcel")
+ SUCCESS -> "${player.name} is now banned from this parcel"
+ }
+ }
+
+ @Cmd("unban", aliases = ["undeny"])
+ @Desc(
+ "Unbans a player from this parcel,",
+ "they will be able to enter it again",
+ shortVersion = "unbans a player from this parcel"
+ )
+ @RequireParcelPrivilege(Privilege.CAN_MANAGE)
+ suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
+ checkOwned(sender)
+
+ val key = toPrivilegeKey(player)
+ checkPrivilege(sender, key)
+
+ return when (parcel.allowEnter(key)) {
+ FAIL_OWNER -> err("The target owns the parcel")
+ FAIL -> err("${player.name} is not currently banned from this parcel")
+ SUCCESS -> "${player.name} is not banned from this parcel anymore"
+ }
+ }
+
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index 721ce2d..155f4f1 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -1,137 +1,137 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.*
-import io.dico.dicore.command.parameter.ArgumentBuffer
-import io.dico.dicore.command.predef.DefaultGroupCommand
-import io.dico.dicore.command.registration.reflect.ReflectiveRegistration
-import io.dico.parcels2.Interactables
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.logger
-import io.dico.parcels2.util.ext.hasPermAdminManage
-import org.bukkit.command.CommandSender
-import java.util.LinkedList
-import java.util.Queue
-
-@Suppress("UsePropertyAccessSyntax")
-fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilder().apply {
- val parcelsAddress = SpecialCommandAddress()
-
- setChatHandler(ParcelsChatHandler())
- addParameterType(false, ParcelParameterType(plugin.parcelProvider))
- addParameterType(false, ProfileParameterType())
- addParameterType(true, ParcelTarget.PType(plugin.parcelProvider, parcelsAddress))
-
- group(parcelsAddress, "parcel", "plot", "plots", "p") {
- addContextFilter(IContextFilter.inheritablePermission("parcels.command"))
- registerCommands(CommandsGeneral(plugin, parcelsAddress))
- registerCommands(CommandsPrivilegesLocal(plugin))
-
- group("option", "opt", "o") {
- setGroupDescription(
- "changes interaction options for this parcel",
- "Sets whether players who are not allowed to",
- "build here can interact with certain things."
- )
-
- group("interact", "i") {
- val command = ParcelOptionsInteractCommand(plugin)
- Interactables.classesById.forEach {
- addSubCommand(it.name, command)
- }
- }
- }
-
- val adminPrivilegesGlobal = CommandsAdminPrivilegesGlobal(plugin)
-
- group("global", "g") {
- registerCommands(CommandsPrivilegesGlobal(plugin, adminVersion = adminPrivilegesGlobal))
- }
-
- group("admin", "a") {
- setCommand(AdminGroupCommand())
- registerCommands(CommandsAdmin(plugin))
-
- group("global", "g") {
- registerCommands(adminPrivilegesGlobal)
- }
- }
-
- if (!logger.isDebugEnabled) return@group
-
- group("debug", "d") {
- registerCommands(CommandsDebug(plugin))
- }
- }
-
- generateHelpAndSyntaxCommands(parcelsAddress)
-}.getDispatcher()
-
-private inline fun CommandBuilder.group(name: String, vararg aliases: String, config: CommandBuilder.() -> Unit) {
- group(name, *aliases)
- config()
- parent()
-}
-
-private inline fun CommandBuilder.group(address: ICommandAddress, name: String, vararg aliases: String, config: CommandBuilder.() -> Unit) {
- group(address, name, *aliases)
- config()
- parent()
-}
-
-private fun CommandBuilder.generateHelpAndSyntaxCommands(root: ICommandAddress): CommandBuilder {
- generateCommands(root, "help", "syntax")
- return this
-}
-
-private fun generateCommands(address: ICommandAddress, vararg names: String) {
- val addresses: Queue<ICommandAddress> = LinkedList()
- addresses.offer(address)
-
- while (addresses.isNotEmpty()) {
- val cur = addresses.poll()
- cur.childrenMainKeys.mapTo(addresses) { cur.getChild(it) }
- if (cur.hasCommand()) {
- ReflectiveRegistration.generateCommands(cur, names)
- }
- }
-}
-
-class SpecialCommandAddress : ChildCommandAddress() {
- private val speciallyTreatedKeys = mutableListOf<String>()
-
- // Used to allow /p h:1 syntax, which is the same as what PlotMe uses.
- var speciallyParsedIndex: Int? = null; private set
-
- fun addSpeciallyTreatedKeys(vararg keys: String) {
- for (key in keys) {
- speciallyTreatedKeys.add(key + ":")
- }
- }
-
- // h:1
- @Throws(CommandException::class)
- override fun getChild(context: ExecutionContext, buffer: ArgumentBuffer): ChildCommandAddress? {
- speciallyParsedIndex = null
-
- val key = buffer.next() ?: return null
- for (specialKey in speciallyTreatedKeys) {
- if (key.startsWith(specialKey)) {
- val result = getChild(specialKey.substring(0, specialKey.length - 1))
- ?: return null
-
- val text = key.substring(specialKey.length)
- val num = text.toIntOrNull() ?: throw CommandException("$text is not a number")
- speciallyParsedIndex = num
-
- return result
- }
- }
-
- return super.getChild(key)
- }
-
-}
-
-private class AdminGroupCommand : DefaultGroupCommand() {
- override fun isVisibleTo(sender: CommandSender) = sender.hasPermAdminManage
-}
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.*
+import io.dico.dicore.command.parameter.ArgumentBuffer
+import io.dico.dicore.command.predef.DefaultGroupCommand
+import io.dico.dicore.command.registration.reflect.ReflectiveRegistration
+import io.dico.parcels2.Interactables
+import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.logger
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import org.bukkit.command.CommandSender
+import java.util.LinkedList
+import java.util.Queue
+
+@Suppress("UsePropertyAccessSyntax")
+fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilder().apply {
+ val parcelsAddress = SpecialCommandAddress()
+
+ setChatHandler(ParcelsChatHandler())
+ addParameterType(false, ParcelParameterType(plugin.parcelProvider))
+ addParameterType(false, ProfileParameterType())
+ addParameterType(true, ParcelTarget.PType(plugin.parcelProvider, parcelsAddress))
+
+ group(parcelsAddress, "parcel", "plot", "plots", "p") {
+ addContextFilter(IContextFilter.inheritablePermission("parcels.command"))
+ registerCommands(CommandsGeneral(plugin, parcelsAddress))
+ registerCommands(CommandsPrivilegesLocal(plugin))
+
+ group("option", "opt", "o") {
+ setGroupDescription(
+ "changes interaction options for this parcel",
+ "Sets whether players who are not allowed to",
+ "build here can interact with certain things."
+ )
+
+ group("interact", "i") {
+ val command = ParcelOptionsInteractCommand(plugin)
+ Interactables.classesById.forEach {
+ addSubCommand(it.name, command)
+ }
+ }
+ }
+
+ val adminPrivilegesGlobal = CommandsAdminPrivilegesGlobal(plugin)
+
+ group("global", "g") {
+ registerCommands(CommandsPrivilegesGlobal(plugin, adminVersion = adminPrivilegesGlobal))
+ }
+
+ group("admin", "a") {
+ setCommand(AdminGroupCommand())
+ registerCommands(CommandsAdmin(plugin))
+
+ group("global", "g") {
+ registerCommands(adminPrivilegesGlobal)
+ }
+ }
+
+ if (!logger.isDebugEnabled) return@group
+
+ group("debug", "d") {
+ registerCommands(CommandsDebug(plugin))
+ }
+ }
+
+ generateHelpAndSyntaxCommands(parcelsAddress)
+}.getDispatcher()
+
+private inline fun CommandBuilder.group(name: String, vararg aliases: String, config: CommandBuilder.() -> Unit) {
+ group(name, *aliases)
+ config()
+ parent()
+}
+
+private inline fun CommandBuilder.group(address: ICommandAddress, name: String, vararg aliases: String, config: CommandBuilder.() -> Unit) {
+ group(address, name, *aliases)
+ config()
+ parent()
+}
+
+private fun CommandBuilder.generateHelpAndSyntaxCommands(root: ICommandAddress): CommandBuilder {
+ generateCommands(root, "help", "syntax")
+ return this
+}
+
+private fun generateCommands(address: ICommandAddress, vararg names: String) {
+ val addresses: Queue<ICommandAddress> = LinkedList()
+ addresses.offer(address)
+
+ while (addresses.isNotEmpty()) {
+ val cur = addresses.poll()
+ cur.childrenMainKeys.mapTo(addresses) { cur.getChild(it) }
+ if (cur.hasCommand()) {
+ ReflectiveRegistration.generateCommands(cur, names)
+ }
+ }
+}
+
+class SpecialCommandAddress : ChildCommandAddress() {
+ private val speciallyTreatedKeys = mutableListOf<String>()
+
+ // Used to allow /p h:1 syntax, which is the same as what PlotMe uses.
+ var speciallyParsedIndex: Int? = null; private set
+
+ fun addSpeciallyTreatedKeys(vararg keys: String) {
+ for (key in keys) {
+ speciallyTreatedKeys.add(key + ":")
+ }
+ }
+
+ // h:1
+ @Throws(CommandException::class)
+ override fun getChild(context: ExecutionContext, buffer: ArgumentBuffer): ChildCommandAddress? {
+ speciallyParsedIndex = null
+
+ val key = buffer.next() ?: return null
+ for (specialKey in speciallyTreatedKeys) {
+ if (key.startsWith(specialKey)) {
+ val result = getChild(specialKey.substring(0, specialKey.length - 1))
+ ?: return null
+
+ val text = key.substring(specialKey.length)
+ val num = text.toIntOrNull() ?: throw CommandException("$text is not a number")
+ speciallyParsedIndex = num
+
+ return result
+ }
+ }
+
+ return super.getChild(key)
+ }
+
+}
+
+private class AdminGroupCommand : DefaultGroupCommand() {
+ override fun isVisibleTo(sender: CommandSender) = sender.hasPermAdminManage
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
index 15548b4..e41fd37 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt
@@ -1,68 +1,68 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.CommandException
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.registration.reflect.ICommandReceiver
-import io.dico.dicore.command.Validate
-import io.dico.parcels2.*
-import io.dico.parcels2.Privilege.*
-import io.dico.parcels2.util.ext.hasPermAdminManage
-import io.dico.parcels2.util.ext.uuid
-import org.bukkit.entity.Player
-import java.lang.reflect.Method
-import kotlin.reflect.full.extensionReceiverParameter
-import kotlin.reflect.full.findAnnotation
-import kotlin.reflect.jvm.jvmErasure
-import kotlin.reflect.jvm.kotlinFunction
-
-@Target(AnnotationTarget.FUNCTION)
-@Retention(AnnotationRetention.RUNTIME)
-annotation class RequireParcelPrivilege(val privilege: Privilege)
-
-/*
-@Target(AnnotationTarget.FUNCTION)
-@Retention(AnnotationRetention.RUNTIME)
-annotation class SuspensionTimeout(val millis: Int)
-*/
-
-open class WorldScope(val world: ParcelWorld) : ICommandReceiver
-open class ParcelScope(val parcel: Parcel) : WorldScope(parcel.world) {
- fun checkCanManage(player: Player, action: String) = Validate.isTrue(parcel.canManage(player), "You must own this parcel to $action")
-}
-
-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
- val require = function.findAnnotation<RequireParcelPrivilege>()
-
- return when (receiverType.jvmErasure) {
- ParcelScope::class -> ParcelScope(parcelProvider.getParcelRequired(player, require?.privilege))
- WorldScope::class -> WorldScope(parcelProvider.getWorldRequired(player, require?.privilege == ADMIN))
- else -> throw InternalError("Invalid command receiver type")
- }
-}
-
-fun ParcelProvider.getWorldRequired(player: Player, admin: Boolean = false): ParcelWorld {
- if (admin) Validate.isTrue(player.hasPermAdminManage, "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 ParcelProvider.getParcelRequired(player: Player, privilege: Privilege? = null): Parcel {
- val parcel = getWorldRequired(player, admin = privilege == ADMIN).getParcelAt(player)
- ?: throw CommandException("You must be in a parcel to use that command")
-
- if (!player.hasPermAdminManage) {
- @Suppress("NON_EXHAUSTIVE_WHEN")
- when (privilege) {
- OWNER ->
- Validate.isTrue(parcel.isOwner(player.uuid), "You must own this parcel to use that command")
- CAN_MANAGE ->
- Validate.isTrue(parcel.canManage(player), "You must have management privileges on this parcel to use that command")
- }
- }
-
- return parcel
-}
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.CommandException
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.registration.reflect.ICommandReceiver
+import io.dico.dicore.command.Validate
+import io.dico.parcels2.*
+import io.dico.parcels2.Privilege.*
+import io.dico.parcels2.util.ext.hasPermAdminManage
+import io.dico.parcels2.util.ext.uuid
+import org.bukkit.entity.Player
+import java.lang.reflect.Method
+import kotlin.reflect.full.extensionReceiverParameter
+import kotlin.reflect.full.findAnnotation
+import kotlin.reflect.jvm.jvmErasure
+import kotlin.reflect.jvm.kotlinFunction
+
+@Target(AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class RequireParcelPrivilege(val privilege: Privilege)
+
+/*
+@Target(AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class SuspensionTimeout(val millis: Int)
+*/
+
+open class WorldScope(val world: ParcelWorld) : ICommandReceiver
+open class ParcelScope(val parcel: Parcel) : WorldScope(parcel.world) {
+ fun checkCanManage(player: Player, action: String) = Validate.isTrue(parcel.canManage(player), "You must own this parcel to $action")
+}
+
+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
+ val require = function.findAnnotation<RequireParcelPrivilege>()
+
+ return when (receiverType.jvmErasure) {
+ ParcelScope::class -> ParcelScope(parcelProvider.getParcelRequired(player, require?.privilege))
+ WorldScope::class -> WorldScope(parcelProvider.getWorldRequired(player, require?.privilege == ADMIN))
+ else -> throw InternalError("Invalid command receiver type")
+ }
+}
+
+fun ParcelProvider.getWorldRequired(player: Player, admin: Boolean = false): ParcelWorld {
+ if (admin) Validate.isTrue(player.hasPermAdminManage, "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 ParcelProvider.getParcelRequired(player: Player, privilege: Privilege? = null): Parcel {
+ val parcel = getWorldRequired(player, admin = privilege == ADMIN).getParcelAt(player)
+ ?: throw CommandException("You must be in a parcel to use that command")
+
+ if (!player.hasPermAdminManage) {
+ @Suppress("NON_EXHAUSTIVE_WHEN")
+ when (privilege) {
+ OWNER ->
+ Validate.isTrue(parcel.isOwner(player.uuid), "You must own this parcel to use that command")
+ CAN_MANAGE ->
+ Validate.isTrue(parcel.canManage(player), "You must have management privileges on this parcel to use that command")
+ }
+ }
+
+ return parcel
+}
+
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
index 23087dc..fbe4333 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
@@ -1,56 +1,56 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.command.*
-import io.dico.dicore.command.parameter.type.ParameterTypes
-import io.dico.parcels2.Interactables
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.Privilege
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
-
-class ParcelOptionsInteractCommand(val plugin: ParcelsPlugin) : Command() {
-
- init {
- setShortDescription("View and/or change the setting")
- setDescription(shortDescription)
- addContextFilter(IContextFilter.PLAYER_ONLY)
- addContextFilter(IContextFilter.INHERIT_PERMISSIONS)
- addParameter("allowed", "new setting", ParameterTypes.BOOLEAN)
- requiredParameters(0)
- }
-
- override fun execute(sender: CommandSender, context: ExecutionContext): String? {
- if (!plugin.storage.isConnected) err("Parcels cannot have their options changed right now because of a database error")
-
- val interactableClass = Interactables[context.address.mainKey]
- val allowed: Boolean? = context.get("allowed")
-
- val parcel = plugin.parcelProvider.getParcelRequired(sender as Player,
- if (allowed == null) Privilege.DEFAULT else Privilege.CAN_MANAGE)
-
- if (allowed == null) {
- val setting = parcel.interactableConfig.isInteractable(interactableClass)
- val default = setting == interactableClass.interactableByDefault
-
- val canColor = context.address.chatHandler.getChatFormatForType(EMessageType.BAD_NEWS)
- val cannotColor = context.address.chatHandler.getChatFormatForType(EMessageType.GOOD_NEWS)
- val resetColor = context.address.chatHandler.getChatFormatForType(EMessageType.RESULT)
-
- val settingString = (if (setting) "${canColor}can" else "${cannotColor}cannot") + resetColor
- val defaultString = if (default) " (default)" else ""
-
- return "Players $settingString interact with ${interactableClass.name} on this parcel$defaultString"
- }
-
- val change = parcel.interactableConfig.setInteractable(interactableClass, allowed)
-
- val interactableClassName = interactableClass.name
- return when {
- allowed && change -> "Other players can now interact with $interactableClassName"
- allowed && !change -> err("Other players could already interact with $interactableClassName")
- change -> "Other players can not interact with $interactableClassName anymore"
- else -> err("Other players were not allowed to interact with $interactableClassName")
- }
- }
-
-}
+package io.dico.parcels2.command
+
+import io.dico.dicore.command.*
+import io.dico.dicore.command.parameter.type.ParameterTypes
+import io.dico.parcels2.Interactables
+import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.Privilege
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+
+class ParcelOptionsInteractCommand(val plugin: ParcelsPlugin) : Command() {
+
+ init {
+ setShortDescription("View and/or change the setting")
+ setDescription(shortDescription)
+ addContextFilter(IContextFilter.PLAYER_ONLY)
+ addContextFilter(IContextFilter.INHERIT_PERMISSIONS)
+ addParameter("allowed", "new setting", ParameterTypes.BOOLEAN)
+ requiredParameters(0)
+ }
+
+ override fun execute(sender: CommandSender, context: ExecutionContext): String? {
+ if (!plugin.storage.isConnected) err("Parcels cannot have their options changed right now because of a database error")
+
+ val interactableClass = Interactables[context.address.mainKey]
+ val allowed: Boolean? = context.get("allowed")
+
+ val parcel = plugin.parcelProvider.getParcelRequired(sender as Player,
+ if (allowed == null) Privilege.DEFAULT else Privilege.CAN_MANAGE)
+
+ if (allowed == null) {
+ val setting = parcel.interactableConfig.isInteractable(interactableClass)
+ val default = setting == interactableClass.interactableByDefault
+
+ val canColor = context.address.chatHandler.getChatFormatForType(EMessageType.BAD_NEWS)
+ val cannotColor = context.address.chatHandler.getChatFormatForType(EMessageType.GOOD_NEWS)
+ val resetColor = context.address.chatHandler.getChatFormatForType(EMessageType.RESULT)
+
+ val settingString = (if (setting) "${canColor}can" else "${cannotColor}cannot") + resetColor
+ val defaultString = if (default) " (default)" else ""
+
+ return "Players $settingString interact with ${interactableClass.name} on this parcel$defaultString"
+ }
+
+ val change = parcel.interactableConfig.setInteractable(interactableClass, allowed)
+
+ val interactableClassName = interactableClass.name
+ return when {
+ allowed && change -> "Other players can now interact with $interactableClassName"
+ allowed && !change -> err("Other players could already interact with $interactableClassName")
+ change -> "Other players can not interact with $interactableClassName anymore"
+ else -> err("Other players were not allowed to interact with $interactableClassName")
+ }
+ }
+
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
index c7083a1..730625e 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
@@ -1,83 +1,83 @@
-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.*
-import io.dico.parcels2.command.ProfileKind.Companion.ANY
-import io.dico.parcels2.command.ProfileKind.Companion.FAKE
-import io.dico.parcels2.command.ProfileKind.Companion.REAL
-import org.bukkit.Location
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
-
-fun invalidInput(parameter: Parameter<*, *>, message: String): Nothing {
- throw CommandException("invalid input for ${parameter.name}: $message")
-}
-
-fun ParcelProvider.getTargetWorld(input: String?, sender: CommandSender, parameter: Parameter<*, *>): ParcelWorld {
- val worldName = input
- ?.takeUnless { it.isEmpty() }
- ?: (sender as? Player)?.world?.name
- ?: invalidInput(parameter, "console cannot omit the world name")
-
- return getWorld(worldName)
- ?: invalidInput(parameter, "$worldName is not a parcel world")
-}
-
-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 = parcelProvider.getTargetWorld(matchResult.groupValues[2], sender, parameter)
-
- val x = matchResult.groupValues[3].toIntOrNull()
- ?: invalidInput(parameter, "couldn't parse int")
-
- val z = matchResult.groupValues[4].toIntOrNull()
- ?: invalidInput(parameter, "couldn't parse int")
-
- return world.getParcelById(x, z)
- ?: invalidInput(parameter, "parcel id is out of range")
- }
-
-}
-
-annotation class ProfileKind(val kind: Int) {
- companion object : ParameterConfig<ProfileKind, Int>(ProfileKind::class.java) {
- const val REAL = 1
- const val FAKE = 2
- const val ANY = REAL or FAKE
-
- override fun toParameterInfo(annotation: ProfileKind): Int {
- return annotation.kind
- }
- }
-}
-
-class ProfileParameterType : ParameterType<PlayerProfile, Int>(PlayerProfile::class.java, ProfileKind) {
-
- override fun parse(parameter: Parameter<PlayerProfile, Int>, sender: CommandSender, buffer: ArgumentBuffer): PlayerProfile {
- val info = parameter.paramInfo ?: REAL
- val allowReal = (info and REAL) != 0
- val allowFake = (info and FAKE) != 0
-
- val input = buffer.next()!!
- return PlayerProfile.byName(input, allowReal, allowFake)
- }
-
- override fun complete(
- parameter: Parameter<PlayerProfile, Int>,
- sender: CommandSender,
- location: Location?,
- buffer: ArgumentBuffer
- ): MutableList<String> {
- logger.info("Completing PlayerProfile: ${buffer.next()}")
- return super.complete(parameter, sender, location, buffer)
- }
-}
+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.*
+import io.dico.parcels2.command.ProfileKind.Companion.ANY
+import io.dico.parcels2.command.ProfileKind.Companion.FAKE
+import io.dico.parcels2.command.ProfileKind.Companion.REAL
+import org.bukkit.Location
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+
+fun invalidInput(parameter: Parameter<*, *>, message: String): Nothing {
+ throw CommandException("invalid input for ${parameter.name}: $message")
+}
+
+fun ParcelProvider.getTargetWorld(input: String?, sender: CommandSender, parameter: Parameter<*, *>): ParcelWorld {
+ val worldName = input
+ ?.takeUnless { it.isEmpty() }
+ ?: (sender as? Player)?.world?.name
+ ?: invalidInput(parameter, "console cannot omit the world name")
+
+ return getWorld(worldName)
+ ?: invalidInput(parameter, "$worldName is not a parcel world")
+}
+
+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 = parcelProvider.getTargetWorld(matchResult.groupValues[2], sender, parameter)
+
+ val x = matchResult.groupValues[3].toIntOrNull()
+ ?: invalidInput(parameter, "couldn't parse int")
+
+ val z = matchResult.groupValues[4].toIntOrNull()
+ ?: invalidInput(parameter, "couldn't parse int")
+
+ return world.getParcelById(x, z)
+ ?: invalidInput(parameter, "parcel id is out of range")
+ }
+
+}
+
+annotation class ProfileKind(val kind: Int) {
+ companion object : ParameterConfig<ProfileKind, Int>(ProfileKind::class.java) {
+ const val REAL = 1
+ const val FAKE = 2
+ const val ANY = REAL or FAKE
+
+ override fun toParameterInfo(annotation: ProfileKind): Int {
+ return annotation.kind
+ }
+ }
+}
+
+class ProfileParameterType : ParameterType<PlayerProfile, Int>(PlayerProfile::class.java, ProfileKind) {
+
+ override fun parse(parameter: Parameter<PlayerProfile, Int>, sender: CommandSender, buffer: ArgumentBuffer): PlayerProfile {
+ val info = parameter.paramInfo ?: REAL
+ val allowReal = (info and REAL) != 0
+ val allowFake = (info and FAKE) != 0
+
+ val input = buffer.next()!!
+ return PlayerProfile.byName(input, allowReal, allowFake)
+ }
+
+ override fun complete(
+ parameter: Parameter<PlayerProfile, Int>,
+ sender: CommandSender,
+ location: Location?,
+ buffer: ArgumentBuffer
+ ): MutableList<String> {
+ logger.info("Completing PlayerProfile: ${buffer.next()}")
+ return super.complete(parameter, sender, location, buffer)
+ }
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
index 8891912..c39c4b6 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
@@ -1,191 +1,191 @@
-package io.dico.parcels2.command
-
-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.PlayerProfile
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.DEFAULT_KIND
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.ID
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER_FAKE
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER_REAL
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.PREFER_OWNED_FOR_DEFAULT
-import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.REAL
-import io.dico.parcels2.storage.Storage
-import io.dico.parcels2.util.math.Vec2i
-import io.dico.parcels2.util.math.floor
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
-
-sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDefault: Boolean) {
-
- abstract suspend fun getParcelSuspend(storage: Storage): Parcel?
-
- class ByID(world: ParcelWorld, val id: Vec2i?, parsedKind: Int, isDefault: Boolean) : ParcelTarget(world, parsedKind, isDefault) {
- override suspend fun getParcelSuspend(storage: Storage): Parcel? = getParcel()
- fun getParcel() = id?.let { world.getParcelById(it) }
- val isPath: Boolean get() = id == null
- }
-
- class ByOwner(
- world: ParcelWorld,
- owner: PlayerProfile,
- val index: Int,
- parsedKind: Int,
- isDefault: Boolean,
- val onResolveFailure: (() -> Unit)? = null
- ) : ParcelTarget(world, parsedKind, isDefault) {
- init {
- if (index < 0) throw IllegalArgumentException("Invalid parcel home index: $index")
- }
-
- var owner = owner; private set
-
- suspend fun resolveOwner(storage: Storage): Boolean {
- val owner = owner
- if (owner is PlayerProfile.Unresolved) {
- this.owner = owner.tryResolveSuspendedly(storage) ?: if (parsedKind and OWNER_FAKE != 0) PlayerProfile.Fake(owner.name)
- else run { onResolveFailure?.invoke(); return false }
- }
- return true
- }
-
- override suspend fun getParcelSuspend(storage: Storage): Parcel? {
- onResolveFailure?.let { resolveOwner(storage) }
-
- val ownedParcelsSerialized = storage.getOwnedParcels(owner).await()
- val ownedParcels = ownedParcelsSerialized
- .filter { it.worldId.equals(world.id) }
- .map { world.getParcelById(it.x, it.z) }
-
- return ownedParcels.getOrNull(index)
- }
- }
-
- annotation class TargetKind(val kind: Int) {
- companion object : ParameterConfig<TargetKind, Int>(TargetKind::class.java) {
- const val ID = 1 // ID
- const val OWNER_REAL = 2 // an owner backed by a UUID
- const val OWNER_FAKE = 4 // an owner not backed by a UUID
-
- const val OWNER = OWNER_REAL or OWNER_FAKE // any owner
- const val ANY = ID or OWNER_REAL or OWNER_FAKE // any
- const val REAL = ID or OWNER_REAL // no owner not backed by a UUID
-
- const val DEFAULT_KIND = REAL
-
- const val PREFER_OWNED_FOR_DEFAULT = 8 // if the kind can be ID and OWNER_REAL, prefer OWNER_REAL for default
- // instead of parcel that the player is in
-
- override fun toParameterInfo(annotation: TargetKind): Int {
- return annotation.kind
- }
- }
- }
-
- class PType(val parcelProvider: ParcelProvider, val parcelAddress: SpecialCommandAddress? = null) :
- ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, TargetKind) {
-
- override fun parse(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget {
- var input = buffer.next()!!
- val worldString = input.substringBefore("/", missingDelimiterValue = "")
- input = input.substringAfter("/")
-
- val world = if (worldString.isEmpty()) {
- val player = requirePlayer(sender, parameter, "the world")
- parcelProvider.getWorld(player.world)
- ?: invalidInput(parameter, "You cannot omit the world if you're not in a parcel world")
- } else {
- 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 OWNER, that is, an owner and index")
- return ByID(world, getId(parameter, input), kind, false)
- }
-
- 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, kind, sender, input)
- return ByOwner(world, owner, index, kind, false, onResolveFailure = { invalidInput(parameter, "The player $input does not exist") })
- }
-
- private fun getId(parameter: Parameter<*, *>, input: String): Vec2i {
- val x = input.substringBefore(',').run {
- toIntOrNull() ?: invalidInput(parameter, "ID(x) must be an integer, $this is not an integer")
- }
- val z = input.substringAfter(',').run {
- toIntOrNull() ?: invalidInput(parameter, "ID(z) must be an integer, $this is not an integer")
- }
- return Vec2i(x, z)
- }
-
- private fun getHomeIndex(parameter: Parameter<*, *>, kind: Int, sender: CommandSender, input: String): Pair<PlayerProfile, Int> {
- val splitIdx = input.indexOf(':')
- val ownerString: String
- val index: Int?
-
- val speciallyParsedIndex = parcelAddress?.speciallyParsedIndex
-
- if (splitIdx == -1) {
-
- if (speciallyParsedIndex == null) {
- // just the index.
- index = input.toIntOrNull()
- ownerString = if (index == null) input else ""
- } else {
- // just the owner.
- index = speciallyParsedIndex
- ownerString = input
- }
-
- } else {
- if (speciallyParsedIndex != null) {
- invalidInput(parameter, "Duplicate home index")
- }
-
- ownerString = input.substring(0, splitIdx)
-
- val indexString = input.substring(splitIdx + 1)
- index = indexString.toIntOrNull()
- ?: invalidInput(parameter, "The home index must be an integer, $indexString is not an integer")
- }
-
- val owner = if (ownerString.isEmpty())
- PlayerProfile(requirePlayer(sender, parameter, "the player"))
- else
- PlayerProfile.byName(ownerString, allowReal = kind and OWNER_REAL != 0, allowFake = kind and OWNER_FAKE != 0)
-
- return owner to (index ?: 0)
- }
-
- private fun requirePlayer(sender: CommandSender, parameter: Parameter<*, *>, objName: String): Player {
- if (sender !is Player) invalidInput(parameter, "console cannot omit the $objName")
- return sender
- }
-
- override fun getDefaultValue(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget? {
- val kind = parameter.paramInfo ?: DEFAULT_KIND
- val useLocation = when {
- kind and REAL == REAL -> kind and PREFER_OWNED_FOR_DEFAULT == 0
- kind and ID != 0 -> true
- kind and OWNER_REAL != 0 -> false
- else -> return null
- }
-
- val player = requirePlayer(sender, parameter, "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.getParcelIdAt(it.x.floor(), it.z.floor())?.pos }
- return ByID(world, id, kind, true)
- }
-
- return ByOwner(world, PlayerProfile(player), parcelAddress?.speciallyParsedIndex ?: 0, kind, true)
- }
- }
-
-}
+package io.dico.parcels2.command
+
+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.PlayerProfile
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.DEFAULT_KIND
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.ID
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER_FAKE
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.OWNER_REAL
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.PREFER_OWNED_FOR_DEFAULT
+import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.REAL
+import io.dico.parcels2.storage.Storage
+import io.dico.parcels2.util.math.Vec2i
+import io.dico.parcels2.util.math.floor
+import org.bukkit.command.CommandSender
+import org.bukkit.entity.Player
+
+sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDefault: Boolean) {
+
+ abstract suspend fun getParcelSuspend(storage: Storage): Parcel?
+
+ class ByID(world: ParcelWorld, val id: Vec2i?, parsedKind: Int, isDefault: Boolean) : ParcelTarget(world, parsedKind, isDefault) {
+ override suspend fun getParcelSuspend(storage: Storage): Parcel? = getParcel()
+ fun getParcel() = id?.let { world.getParcelById(it) }
+ val isPath: Boolean get() = id == null
+ }
+
+ class ByOwner(
+ world: ParcelWorld,
+ owner: PlayerProfile,
+ val index: Int,
+ parsedKind: Int,
+ isDefault: Boolean,
+ val onResolveFailure: (() -> Unit)? = null
+ ) : ParcelTarget(world, parsedKind, isDefault) {
+ init {
+ if (index < 0) throw IllegalArgumentException("Invalid parcel home index: $index")
+ }
+
+ var owner = owner; private set
+
+ suspend fun resolveOwner(storage: Storage): Boolean {
+ val owner = owner
+ if (owner is PlayerProfile.Unresolved) {
+ this.owner = owner.tryResolveSuspendedly(storage) ?: if (parsedKind and OWNER_FAKE != 0) PlayerProfile.Fake(owner.name)
+ else run { onResolveFailure?.invoke(); return false }
+ }
+ return true
+ }
+
+ override suspend fun getParcelSuspend(storage: Storage): Parcel? {
+ onResolveFailure?.let { resolveOwner(storage) }
+
+ val ownedParcelsSerialized = storage.getOwnedParcels(owner).await()
+ val ownedParcels = ownedParcelsSerialized
+ .filter { it.worldId.equals(world.id) }
+ .map { world.getParcelById(it.x, it.z) }
+
+ return ownedParcels.getOrNull(index)
+ }
+ }
+
+ annotation class TargetKind(val kind: Int) {
+ companion object : ParameterConfig<TargetKind, Int>(TargetKind::class.java) {
+ const val ID = 1 // ID
+ const val OWNER_REAL = 2 // an owner backed by a UUID
+ const val OWNER_FAKE = 4 // an owner not backed by a UUID
+
+ const val OWNER = OWNER_REAL or OWNER_FAKE // any owner
+ const val ANY = ID or OWNER_REAL or OWNER_FAKE // any
+ const val REAL = ID or OWNER_REAL // no owner not backed by a UUID
+
+ const val DEFAULT_KIND = REAL
+
+ const val PREFER_OWNED_FOR_DEFAULT = 8 // if the kind can be ID and OWNER_REAL, prefer OWNER_REAL for default
+ // instead of parcel that the player is in
+
+ override fun toParameterInfo(annotation: TargetKind): Int {
+ return annotation.kind
+ }
+ }
+ }
+
+ class PType(val parcelProvider: ParcelProvider, val parcelAddress: SpecialCommandAddress? = null) :
+ ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, TargetKind) {
+
+ override fun parse(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget {
+ var input = buffer.next()!!
+ val worldString = input.substringBefore("/", missingDelimiterValue = "")
+ input = input.substringAfter("/")
+
+ val world = if (worldString.isEmpty()) {
+ val player = requirePlayer(sender, parameter, "the world")
+ parcelProvider.getWorld(player.world)
+ ?: invalidInput(parameter, "You cannot omit the world if you're not in a parcel world")
+ } else {
+ 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 OWNER, that is, an owner and index")
+ return ByID(world, getId(parameter, input), kind, false)
+ }
+
+ 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, kind, sender, input)
+ return ByOwner(world, owner, index, kind, false, onResolveFailure = { invalidInput(parameter, "The player $input does not exist") })
+ }
+
+ private fun getId(parameter: Parameter<*, *>, input: String): Vec2i {
+ val x = input.substringBefore(',').run {
+ toIntOrNull() ?: invalidInput(parameter, "ID(x) must be an integer, $this is not an integer")
+ }
+ val z = input.substringAfter(',').run {
+ toIntOrNull() ?: invalidInput(parameter, "ID(z) must be an integer, $this is not an integer")
+ }
+ return Vec2i(x, z)
+ }
+
+ private fun getHomeIndex(parameter: Parameter<*, *>, kind: Int, sender: CommandSender, input: String): Pair<PlayerProfile, Int> {
+ val splitIdx = input.indexOf(':')
+ val ownerString: String
+ val index: Int?
+
+ val speciallyParsedIndex = parcelAddress?.speciallyParsedIndex
+
+ if (splitIdx == -1) {
+
+ if (speciallyParsedIndex == null) {
+ // just the index.
+ index = input.toIntOrNull()
+ ownerString = if (index == null) input else ""
+ } else {
+ // just the owner.
+ index = speciallyParsedIndex
+ ownerString = input
+ }
+
+ } else {
+ if (speciallyParsedIndex != null) {
+ invalidInput(parameter, "Duplicate home index")
+ }
+
+ ownerString = input.substring(0, splitIdx)
+
+ val indexString = input.substring(splitIdx + 1)
+ index = indexString.toIntOrNull()
+ ?: invalidInput(parameter, "The home index must be an integer, $indexString is not an integer")
+ }
+
+ val owner = if (ownerString.isEmpty())
+ PlayerProfile(requirePlayer(sender, parameter, "the player"))
+ else
+ PlayerProfile.byName(ownerString, allowReal = kind and OWNER_REAL != 0, allowFake = kind and OWNER_FAKE != 0)
+
+ return owner to (index ?: 0)
+ }
+
+ private fun requirePlayer(sender: CommandSender, parameter: Parameter<*, *>, objName: String): Player {
+ if (sender !is Player) invalidInput(parameter, "console cannot omit the $objName")
+ return sender
+ }
+
+ override fun getDefaultValue(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget? {
+ val kind = parameter.paramInfo ?: DEFAULT_KIND
+ val useLocation = when {
+ kind and REAL == REAL -> kind and PREFER_OWNED_FOR_DEFAULT == 0
+ kind and ID != 0 -> true
+ kind and OWNER_REAL != 0 -> false
+ else -> return null
+ }
+
+ val player = requirePlayer(sender, parameter, "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.getParcelIdAt(it.x.floor(), it.z.floor())?.pos }
+ return ByID(world, id, kind, true)
+ }
+
+ return ByOwner(world, PlayerProfile(player), parcelAddress?.speciallyParsedIndex ?: 0, kind, true)
+ }
+ }
+
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt
index b616f77..52f1104 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt
@@ -1,24 +1,24 @@
-package io.dico.parcels2.command
-
-import io.dico.dicore.Formatting
-import io.dico.dicore.command.EMessageType
-import io.dico.dicore.command.ExecutionContext
-import io.dico.dicore.command.chat.AbstractChatHandler
-import io.dico.parcels2.util.ext.plus
-
-class ParcelsChatHandler : AbstractChatHandler() {
-
- override fun getMessagePrefixForType(type: EMessageType?): String {
- return Formatting.RED + "[Parcels] "
- }
-
- override fun createMessage(context: ExecutionContext, type: EMessageType, message: String?): String? {
- if (message.isNullOrEmpty()) return null
- var result = getChatFormatForType(type) + message
- if (context.address.mainKey != "info") {
- result = getMessagePrefixForType(type) + result
- }
- return result
- }
-
+package io.dico.parcels2.command
+
+import io.dico.dicore.Formatting
+import io.dico.dicore.command.EMessageType
+import io.dico.dicore.command.ExecutionContext
+import io.dico.dicore.command.chat.AbstractChatHandler
+import io.dico.parcels2.util.ext.plus
+
+class ParcelsChatHandler : AbstractChatHandler() {
+
+ override fun getMessagePrefixForType(type: EMessageType?): String {
+ return Formatting.RED + "[Parcels] "
+ }
+
+ override fun createMessage(context: ExecutionContext, type: EMessageType, message: String?): String? {
+ if (message.isNullOrEmpty()) return null
+ var result = getChatFormatForType(type) + message
+ if (context.address.mainKey != "info") {
+ result = getMessagePrefixForType(type) + result
+ }
+ return result
+ }
+
} \ No newline at end of file