diff options
author | Dico200 <dico.karssiens@gmail.com> | 2018-07-24 02:05:57 +0100 |
---|---|---|
committer | Dico200 <dico.karssiens@gmail.com> | 2018-07-24 02:05:57 +0100 |
commit | a26c25320a63806bf9a3bdf1e8dd4fd91962c41c (patch) | |
tree | 54065e11da27390ee9d165b629bd1ae24bd027f3 | |
parent | d15d1b767bc89d087fd46450cb5e62fe0c4e9e61 (diff) |
Implement /p home
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") |