summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2018-07-24 02:05:57 +0100
committerDico200 <dico.karssiens@gmail.com>2018-07-24 02:05:57 +0100
commita26c25320a63806bf9a3bdf1e8dd4fd91962c41c (patch)
tree54065e11da27390ee9d165b629bd1ae24bd027f3
parentd15d1b767bc89d087fd46450cb5e62fe0c4e9e61 (diff)
Implement /p home
-rw-r--r--src/main/kotlin/io/dico/parcels2/Parcel.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt81
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommands.kt33
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt1
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/SerializableTypes.kt13
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/PlayerExtensions.kt3
6 files changed, 112 insertions, 21 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/Parcel.kt b/src/main/kotlin/io/dico/parcels2/Parcel.kt
index ef45e08..b3eb7c9 100644
--- a/src/main/kotlin/io/dico/parcels2/Parcel.kt
+++ b/src/main/kotlin/io/dico/parcels2/Parcel.kt
@@ -40,7 +40,7 @@ interface ParcelData {
*/
class Parcel(val world: ParcelWorld, val pos: Vec2i) : ParcelData {
val id get() = "${pos.x}:${pos.z}"
-
+ val homeLocation get() = world.generator.getHomeLocation(this)
var data: ParcelData = ParcelDataHolder(); private set
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index 1cca5be..9b09192 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -6,10 +6,9 @@ import io.dico.dicore.command.ICommandDispatcher
import io.dico.dicore.command.parameter.ArgumentBuffer
import io.dico.dicore.command.parameter.IParameter
import io.dico.dicore.command.parameter.type.ParameterType
-import io.dico.parcels2.Parcel
-import io.dico.parcels2.ParcelsPlugin
-import io.dico.parcels2.Worlds
-import io.dico.parcels2.debugging
+import io.dico.parcels2.*
+import org.bukkit.Bukkit
+import org.bukkit.OfflinePlayer
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
@@ -18,6 +17,7 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher {
//@formatter:off
return CommandBuilder()
.addParameterType(false, ParcelParameterType(plugin.worlds))
+ .addParameterType(false, ParcelHomeParameterType(plugin.worlds))
.group("parcel", "plot", "plots", "p")
.registerCommands(ParcelCommands(plugin))
.putDebugCommands(plugin)
@@ -35,25 +35,28 @@ private fun CommandBuilder.putDebugCommands(plugin: ParcelsPlugin): CommandBuild
//@formatter:on
}
-private val regex = Regex.fromLiteral("((.+)->)?([0-9]+):([0-9]+)")
+private fun invalidInput(parameter: IParameter<*>, message: String): Nothing {
+ throw CommandException("invalid input for ${parameter.name}: $message")
+}
-private class ParcelParameterType(val worlds: Worlds) : ParameterType<Parcel, Unit>(Parcel::class.java) {
+private fun Worlds.getTargetWorld(input: String?, sender: CommandSender, parameter: IParameter<*>): ParcelWorld {
+ val worldName = input
+ ?.takeUnless { it.isEmpty() }
+ ?: (sender as? Player)?.world?.name
+ ?: invalidInput(parameter, "console cannot omit the world name")
- private fun invalidInput(parameter: IParameter<*>, message: String): Nothing {
- throw CommandException("invalid input for ${parameter.name}: $message")
- }
+ return getWorld(worldName)
+ ?: invalidInput(parameter, "$worldName is not a parcel world")
+}
+
+private class ParcelParameterType(val worlds: Worlds) : ParameterType<Parcel, Unit>(Parcel::class.java) {
+ val regex = Regex.fromLiteral("((.+)->)?([0-9]+):([0-9]+)")
override fun parse(parameter: IParameter<Parcel>, sender: CommandSender, buffer: ArgumentBuffer): Parcel {
val matchResult = regex.matchEntire(buffer.next())
?: invalidInput(parameter, "must match (w->)?a:b (/${regex.pattern}/)")
- val worldName = matchResult.groupValues[2]
- .takeUnless { it.isEmpty() }
- ?: (sender as? Player)?.world?.name
- ?: invalidInput(parameter, "console cannot omit the world name")
-
- val world = worlds.getWorld(worldName)
- ?: invalidInput(parameter, "$worldName is not a parcel world")
+ val world = worlds.getTargetWorld(matchResult.groupValues[2], sender, parameter)
val x = matchResult.groupValues[3].toIntOrNull()
?: invalidInput(parameter, "couldn't parse int")
@@ -66,3 +69,49 @@ private class ParcelParameterType(val worlds: Worlds) : ParameterType<Parcel, Un
}
}
+
+class NamedParcelTarget(val world: ParcelWorld, val player: OfflinePlayer, val index: Int)
+
+private class ParcelHomeParameterType(val worlds: Worlds) : ParameterType<NamedParcelTarget, Unit>(NamedParcelTarget::class.java) {
+ val regex = Regex.fromLiteral("((.+)->)?(.+)|((.+):([0-9]+))")
+
+ private fun requirePlayer(sender: CommandSender, parameter: IParameter<*>): Player {
+ if (sender !is Player) invalidInput(parameter, "console cannot omit the player name")
+ return sender
+ }
+
+ @Suppress("UsePropertyAccessSyntax")
+ private fun getOfflinePlayer(input: String, parameter: IParameter<*>) = Bukkit.getOfflinePlayer(input)
+ ?.takeIf { it.isOnline() || it.hasPlayedBefore() }
+ ?: invalidInput(parameter, "do not know who $input is")
+
+ override fun parse(parameter: IParameter<NamedParcelTarget>, sender: CommandSender, buffer: ArgumentBuffer): NamedParcelTarget {
+ val matchResult = regex.matchEntire(buffer.next())
+ ?: invalidInput(parameter, "must be a player, index, or player:index (/${regex.pattern}/)")
+
+ val world = worlds.getTargetWorld(matchResult.groupValues[2], sender, parameter)
+
+ matchResult.groupValues[3].takeUnless { it.isEmpty() }?.let {
+ // first group was matched, it's a player or an int
+ it.toIntOrNull()?.let {
+ requirePlayer(sender, parameter)
+ return NamedParcelTarget(world, sender as Player, it)
+ }
+
+ return NamedParcelTarget(world, getOfflinePlayer(it, parameter), 0)
+ }
+
+ val player = getOfflinePlayer(matchResult.groupValues[5], parameter)
+ val index = matchResult.groupValues[6].toIntOrNull()
+ ?: invalidInput(parameter, "couldn't parse int")
+
+ return NamedParcelTarget(world, player, index)
+ }
+
+ override fun getDefaultValue(parameter: IParameter<NamedParcelTarget>, sender: CommandSender, buffer: ArgumentBuffer): NamedParcelTarget {
+ val world = worlds.getTargetWorld(null, sender, parameter)
+ val player = requirePlayer(sender, parameter)
+ return NamedParcelTarget(world, player, 0)
+ }
+
+}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommands.kt
index 016ad22..6cc5e02 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommands.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommands.kt
@@ -4,12 +4,16 @@ import io.dico.dicore.command.CommandException
import io.dico.dicore.command.ExecutionContext
import io.dico.dicore.command.annotation.Cmd
import io.dico.dicore.command.annotation.Desc
+import io.dico.dicore.command.annotation.RequireParameters
import io.dico.parcels2.ParcelOwner
import io.dico.parcels2.ParcelsPlugin
+import io.dico.parcels2.storage.getParcelBySerializedValue
+import io.dico.parcels2.util.hasParcelHomeOthers
import io.dico.parcels2.util.parcelLimit
import io.dico.parcels2.util.uuid
import org.bukkit.entity.Player
+@Suppress("unused")
class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin {
override val worlds = plugin.worlds
@@ -35,7 +39,7 @@ class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin
val parcel = world.nextEmptyParcel()
?: error("This world is full, please ask an admin to upsize it")
parcel.owner = ParcelOwner(uuid = player.uuid)
- player.teleport(world.generator.getHomeLocation(parcel))
+ player.teleport(parcel.homeLocation)
"Enjoy your new parcel!"
}
}
@@ -47,5 +51,32 @@ class ParcelCommands(override val plugin: ParcelsPlugin) : HasWorlds, HasPlugin
shortVersion = "displays information about this parcel")
fun cmdInfo(player: Player) = requireInParcel(player) { parcel.infoString }
+ @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)
+ fun cmdHome(player: Player, context: ExecutionContext, target: NamedParcelTarget) {
+ if (player !== target.player && !player.hasParcelHomeOthers) {
+ error("You do not have permission to teleport to other people's parcels")
+ }
+
+ return delegateCommandAsync(context) {
+ val ownedParcelsResult = plugin.storage.getOwnedParcels(ParcelOwner(uuid = target.player.uuid)).await()
+ awaitSynchronousTask {
+ val uuid = target.player.uuid
+ val ownedParcels = ownedParcelsResult
+ .map { worlds.getParcelBySerializedValue(it) }
+ .filter { it != null && it.world == target.world && it.owner?.uuid == uuid }
+
+ val targetMatch = ownedParcels.getOrNull(target.index)
+ ?: error("The specified parcel could not be matched")
+
+ player.teleport(targetMatch.homeLocation)
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt b/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
index 47efc87..fdbb9e2 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
@@ -176,6 +176,7 @@ class ExposedBacking(val dataSource: DataSource) : Backing {
}
+ // TODO order by some new column
override suspend fun getOwnedParcels(user: ParcelOwner): List<SerializableParcel> = transaction {
val where: SqlExpressionBuilder.() -> Op<Boolean>
diff --git a/src/main/kotlin/io/dico/parcels2/storage/SerializableTypes.kt b/src/main/kotlin/io/dico/parcels2/storage/SerializableTypes.kt
index 121e251..4c25aeb 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/SerializableTypes.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/SerializableTypes.kt
@@ -2,6 +2,7 @@ package io.dico.parcels2.storage
import io.dico.parcels2.Parcel
import io.dico.parcels2.ParcelWorld
+import io.dico.parcels2.Worlds
import io.dico.parcels2.math.Vec2i
import org.bukkit.Bukkit
import org.bukkit.World
@@ -15,7 +16,7 @@ data class SerializableWorld(val name: String? = null,
}
val world: World? by lazy { uid?.let { Bukkit.getWorld(it) } ?: name?.let { Bukkit.getWorld(it) } }
- val parcelWorld: ParcelWorld? by lazy { TODO() }
+ //val parcelWorld: ParcelWorld? by lazy { TODO() }
}
/**
@@ -24,5 +25,13 @@ data class SerializableWorld(val name: String? = null,
data class SerializableParcel(val world: SerializableWorld,
val pos: Vec2i) {
- val parcel: Parcel? by lazy { TODO() }
+ //val parcel: Parcel? by lazy { TODO() }
+}
+
+fun Worlds.getWorldBySerializedValue(input: SerializableWorld): ParcelWorld? {
+ return input.world?.let { getWorld(it) }
+}
+
+fun Worlds.getParcelBySerializedValue(input: SerializableParcel): Parcel? {
+ return getWorldBySerializedValue(input.world)?.parcelByID(input.pos)
} \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/util/PlayerExtensions.kt b/src/main/kotlin/io/dico/parcels2/util/PlayerExtensions.kt
index 3424655..4953e8a 100644
--- a/src/main/kotlin/io/dico/parcels2/util/PlayerExtensions.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/PlayerExtensions.kt
@@ -3,10 +3,11 @@ package io.dico.parcels2.util
import io.dico.dicore.Formatting
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
+import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin
-inline val Player.uuid get() = uniqueId
+inline val OfflinePlayer.uuid get() = uniqueId
inline val Player.hasBanBypass get() = hasPermission("parcels.admin.bypass.ban")
inline val Player.hasBuildAnywhere get() = hasPermission("parcels.admin.bypass.build")
inline val Player.hasGamemodeBypass get() = hasPermission("parcels.admin.bypass.gamemode")