summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt')
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt90
1 files changed, 47 insertions, 43 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
index cbab80a..abf7d40 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
@@ -5,20 +5,23 @@ import io.dico.dicore.command.parameter.Parameter
import io.dico.dicore.command.parameter.type.ParameterConfig
import io.dico.dicore.command.parameter.type.ParameterType
import io.dico.parcels2.*
+import io.dico.parcels2.storage.Storage
import io.dico.parcels2.util.Vec2i
-import io.dico.parcels2.util.floor
-import kotlinx.coroutines.experimental.Deferred
+import io.dico.parcels2.util.ext.floor
+import kotlinx.coroutines.CoroutineStart.*
+import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.async
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
-sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
+sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDefault: Boolean) {
- abstract suspend fun ParcelsPlugin.getParcelSuspend(): Parcel?
+ abstract suspend fun getParcelSuspend(storage: Storage): Parcel?
- fun ParcelsPlugin.getParcelDeferred(): Deferred<Parcel?> = functionHelper.deferUndispatchedOnMainThread { getParcelSuspend() }
+ fun ParcelsPlugin.getParcelDeferred(): Deferred<Parcel?> = async(start = UNDISPATCHED) { getParcelSuspend(storage) }
- class ByID(world: ParcelWorld, val id: Vec2i?, isDefault: Boolean) : ParcelTarget(world, isDefault) {
- override suspend fun ParcelsPlugin.getParcelSuspend(): Parcel? = getParcel()
+ 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
}
@@ -26,46 +29,40 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
class ByOwner(world: ParcelWorld,
owner: PlayerProfile,
val index: Int,
+ parsedKind: Int,
isDefault: Boolean,
- val onResolveFailure: (() -> Unit)? = null) : ParcelTarget(world, isDefault) {
+ val onResolveFailure: (() -> Unit)? = null) : ParcelTarget(world, parsedKind, isDefault) {
init {
if (index < 0) throw IllegalArgumentException("Invalid parcel home index: $index")
}
var owner = owner; private set
- override suspend fun ParcelsPlugin.getParcelSuspend(): Parcel? {
- onResolveFailure?.let { onFail ->
- val owner = owner
- if (owner is PlayerProfile.Unresolved) {
- val new = owner.tryResolveSuspendedly(storage)
- if (new == null) {
- onFail()
- return@let
- }
- this@ByOwner.owner = new
- }
+ 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
- .map { parcelProvider.getParcelById(it) }
- .filter { it != null && world == it.world && owner == it.owner }
+ .filter { it.worldId.equals(world.id) }
+ .map { world.getParcelById(it.x, it.z) }
return ownedParcels.getOrNull(index)
}
}
- annotation class Kind(val kind: Int)
-
- companion object Config : ParameterConfig<Kind, Int>(Kind::class.java) {
- override fun toParameterInfo(annotation: Kind): Int {
- return annotation.kind
- }
-
+ companion object {
const val ID = 1 // ID
const val OWNER_REAL = 2 // an owner backed by a UUID
- const val OWNER_FAKE = 3 // an owner not 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
@@ -73,11 +70,18 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
const val DEFAULT_KIND = REAL
- const val PREFER_OWNED_FOR_DEFAULT = 4 // if the kind can be ID and OWNER_REAL, prefer OWNER_REAL for default
+ 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
}
- class PType(val parcelProvider: ParcelProvider) : ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, ParcelTarget.Config) {
+ annotation class Kind(val kind: Int)
+ private object Config : ParameterConfig<Kind, Int>(Kind::class.java) {
+ override fun toParameterInfo(annotation: Kind): Int {
+ return annotation.kind
+ }
+ }
+
+ class PType(val parcelProvider: ParcelProvider) : ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, Config) {
override fun parse(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget {
var input = buffer.next()
@@ -95,12 +99,12 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
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), false)
+ 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, false, onResolveFailure = { invalidInput(parameter, "The player $input does not exist") })
+ return ByOwner(world, owner, index, kind, false, onResolveFailure = { invalidInput(parameter, "The player $input does not exist") })
}
private fun getId(parameter: Parameter<*, *>, input: String): Vec2i {
@@ -116,15 +120,18 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
private fun getHomeIndex(parameter: Parameter<*, *>, kind: Int, sender: CommandSender, input: String): Pair<PlayerProfile, Int> {
val splitIdx = input.indexOf(':')
val ownerString: String
- val indexString: String
+ val index: Int?
if (splitIdx == -1) {
// just the index.
- ownerString = ""
- indexString = input
+ index = input.toIntOrNull()
+ ownerString = if (index == null) input else ""
} else {
ownerString = input.substring(0, splitIdx)
- indexString = input.substring(splitIdx + 1)
+
+ 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())
@@ -132,10 +139,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
else
PlayerProfile.byName(ownerString, allowReal = kind and OWNER_REAL != 0, allowFake = kind and OWNER_FAKE != 0)
- val index = if (indexString.isEmpty()) 0 else indexString.toIntOrNull()
- ?: invalidInput(parameter, "The home index must be an integer, $indexString is not an integer")
-
- return owner to index
+ return owner to (index ?: 0)
}
private fun requirePlayer(sender: CommandSender, parameter: Parameter<*, *>, objName: String): Player {
@@ -156,10 +160,10 @@ sealed class ParcelTarget(val world: ParcelWorld, val isDefault: Boolean) {
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, true)
+ return ByID(world, id, kind, true)
}
- return ByOwner(world, PlayerProfile(player), 0, true)
+ return ByOwner(world, PlayerProfile(player), 0, kind, true)
}
}