summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico <dico.karssiens@gmail.com>2018-09-27 04:41:58 +0100
committerDico <dico.karssiens@gmail.com>2018-09-27 04:41:58 +0100
commit307b7aee4af34e47139259db7049a85c682b7be2 (patch)
tree398ff3360f90e49cdc2a10d7872f6c6f787472bb
parentcdaba0ebd5b48d1f2d4579c873d83fdf6ea1a074 (diff)
Tweaks
-rw-r--r--src/main/kotlin/io/dico/parcels2/PlayerProfile.kt141
-rw-r--r--src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt8
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt13
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt15
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt4
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt69
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt19
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt6
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt9
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt26
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt49
-rw-r--r--src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/ListenerHelper.kt16
-rw-r--r--src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt12
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/UUIDUtil.kt14
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt3
-rw-r--r--src/main/kotlin/io/dico/parcels2/util/ext/Player.kt4
19 files changed, 162 insertions, 252 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
index ae73639..99b2b5f 100644
--- a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
+++ b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt
@@ -3,13 +3,11 @@
package io.dico.parcels2
import io.dico.parcels2.storage.Storage
-import io.dico.parcels2.util.PLAYER_NAME_PLACEHOLDER
-import io.dico.parcels2.util.getPlayerName
+import io.dico.parcels2.util.ext.PLAYER_NAME_PLACEHOLDER
import io.dico.parcels2.util.ext.isValid
import io.dico.parcels2.util.ext.uuid
-import kotlinx.coroutines.Deferred
-import kotlinx.coroutines.Unconfined
-import kotlinx.coroutines.async
+import io.dico.parcels2.util.getOfflinePlayer
+import io.dico.parcels2.util.getPlayerName
import org.bukkit.Bukkit
import org.bukkit.OfflinePlayer
import java.util.UUID
@@ -70,8 +68,7 @@ interface PlayerProfile {
if (input == Star.name) return Star
- return Bukkit.getOfflinePlayer(input).takeIf { it.isValid }?.let { PlayerProfile(it) }
- ?: Unresolved(input)
+ return getOfflinePlayer(input)?.let { PlayerProfile(it) } ?: Unresolved(input)
}
}
@@ -83,8 +80,7 @@ interface PlayerProfile {
override val notNullName: String
get() = nameOrBukkitName ?: PLAYER_NAME_PLACEHOLDER
- val player: OfflinePlayer? get() = Bukkit.getOfflinePlayer(uuid).takeIf { it.isValid }
- val playerUnchecked: OfflinePlayer get() = Bukkit.getOfflinePlayer(uuid)
+ val player: OfflinePlayer? get() = getOfflinePlayer(uuid)
override fun matches(player: OfflinePlayer, allowNameMatch: Boolean): Boolean {
return uuid == player.uuid || (allowNameMatch && name?.let { it == player.name } == true)
@@ -147,10 +143,6 @@ interface PlayerProfile {
return other is Unresolved && name == other.name
}
- fun tryResolve(storage: Storage): Deferred<Real?> {
- return async(Unconfined) { tryResolveSuspendedly(storage) }
- }
-
suspend fun tryResolveSuspendedly(storage: Storage): Real? {
return storage.getPlayerUuidForName(name).await()?.let { resolve(it) }
}
@@ -178,120 +170,9 @@ interface PlayerProfile {
}
-
-/*
-
-
-/**
- * This class can represent:
- *
- * An existing player
- * A fake player (with only a name)
- * An existing player who must have its uuid resolved from the database (after checking against Bukkit OfflinePlayer)
- * STAR profile, which matches everyone. This profile is considered a REAL player, because it can have a privilege.
- */
-class PlayerProfile2 private constructor(uuid: UUID?,
- val name: String?,
- val isReal: Boolean = uuid != null) {
- private var _uuid: UUID? = uuid
- val notNullName: String get() = name ?: getPlayerNameOrDefault(uuid!!)
-
- val uuid: UUID? get() = _uuid ?: if (isReal) throw IllegalStateException("This PlayerProfile must be resolved first") else null
-
- companion object {
- // below uuid is just a randomly generated one (version 4). Hopefully no minecraft player will ever have it :)
- val star = PlayerProfile(UUID.fromString("7d09c4c6-117d-4f36-9778-c4d24618cee1"), "*", true)
-
- fun nameless(player: OfflinePlayer): PlayerProfile {
- if (!player.isValid) throw IllegalArgumentException("The given OfflinePlayer is not valid")
- return PlayerProfile(player.uuid)
- }
-
- fun fromNameAndUuid(name: String?, uuid: UUID?): PlayerProfile? {
- if (name == null && uuid == null) return null
- if (star.name == name && star._uuid == uuid) return star
- return PlayerProfile(uuid, name)
- }
-
- fun realPlayerByName(name: String): PlayerProfile {
- return fromString(name, allowReal = true, allowFake = false)
- }
-
- fun fromString(input: String, allowReal: Boolean = true, allowFake: Boolean = false): PlayerProfile {
- if (!allowReal) {
- if (!allowFake) throw IllegalArgumentException("at least one of allowReal and allowFake must be true")
- return PlayerProfile(input)
- }
-
- if (input == star.name) return star
-
- return Bukkit.getOfflinePlayer(input).takeIf { it.isValid }?.let { PlayerProfile(it) }
- ?: PlayerProfile(null, input, !allowFake)
- }
-
- operator fun createWith(name: String): PlayerProfile {
- if (name == star.name) return star
- return PlayerProfile(null, name)
- }
-
- operator fun createWith(uuid: UUID): PlayerProfile {
- if (uuid == star.uuid) return star
- return PlayerProfile(uuid, null)
- }
-
- operator fun createWith(player: OfflinePlayer): PlayerProfile {
- // avoid UUID comparison against STAR
- return if (player.isValid) PlayerProfile(player.uuid, player.name) else createWith(player.name)
- }
- }
-
- val isStar: Boolean get() = this === star || (name == star.name && _uuid == star._uuid)
- val hasUUID: Boolean get() = _uuid != null
- val mustBeResolved: Boolean get() = isReal && _uuid == null
-
- val onlinePlayer: Player? get() = uuid?.let { Bukkit.getPlayer(uuid) }
-
- val onlinePlayerAllowingNameMatch: Player? get() = onlinePlayer ?: name?.let { Bukkit.getPlayerExact(name) }
- val offlinePlayer: OfflinePlayer? get() = uuid?.let { Bukkit.getOfflinePlayer(it).takeIf { it.isValid } }
- val offlinePlayerAllowingNameMatch: OfflinePlayer?
- get() = offlinePlayer ?: Bukkit.getOfflinePlayer(name).takeIf { it.isValid }
-
- fun matches(player: OfflinePlayer, allowNameMatch: Boolean = false): Boolean {
- if (isStar) return true
- return uuid?.let { it == player.uniqueId } ?: false
- || (allowNameMatch && name?.let { it == player.name } ?: false)
- }
-
- fun equals(other: PlayerProfile): Boolean {
- return if (_uuid != null) _uuid == other._uuid
- else other._uuid == null && isReal == other.isReal && name == other.name
- }
-
- override fun equals(other: Any?): Boolean {
- return other is PlayerProfile && equals(other)
- }
-
- override fun hashCode(): Int {
- return _uuid?.hashCode() ?: name!!.hashCode()
- }
-
- /**
- * resolve the uuid of this player profile if [mustBeResolved], using specified [storage].
- * returns true if the PlayerProfile has a uuid after this call.
- */
- suspend fun resolve(storage: Storage): Boolean {
- if (mustBeResolved) {
- val uuid = storage.getPlayerUuidForName(name!!).await()
- _uuid = uuid
- return uuid != null
- }
- return _uuid != null
- }
-
- fun resolve(uuid: UUID) {
- if (isReal && _uuid == null) {
- _uuid = uuid
- }
- }
-}
-*/
+suspend fun PlayerProfile.resolved(storage: Storage, resolveToFake: Boolean = false): PlayerProfile? =
+ when (this) {
+ is PlayerProfile.Unresolved -> tryResolveSuspendedly(storage)
+ ?: if (resolveToFake) PlayerProfile.Fake(name) else null
+ else -> this
+ } \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt
index 7201a06..7162561 100644
--- a/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt
+++ b/src/main/kotlin/io/dico/parcels2/blockvisitor/WorkDispatcher.kt
@@ -24,7 +24,6 @@ data class TickWorktimeOptions(var workTime: Int, var tickInterval: Int)
interface WorkDispatcher {
/**
* Submit a [task] that should be run synchronously, but limited such that it does not stall the server
- * a bunch
*/
fun dispatch(task: WorkerTask): Worker
@@ -89,11 +88,6 @@ interface Worker : WorkerAndScopeMembersUnion {
* Await completion of this worker
*/
suspend fun awaitCompletion()
-
- /**
- * An object attached to this worker
- */
- //val attachment: Any?
}
interface WorkerScope : WorkerAndScopeMembersUnion {
@@ -114,7 +108,7 @@ interface WorkerScope : WorkerAndScopeMembersUnion {
/**
* Get a [WorkerScope] that is responsible for [portion] part of the progress
- * If [portion] is negative, the remainder of the progress is used
+ * If [portion] is negative, the remaining progress is used
*/
fun delegateWork(portion: Double = -1.0): WorkerScope
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
index a660fc0..79faf36 100644
--- a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
@@ -20,12 +20,8 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
}
- protected fun error(message: String): Nothing {
- throw CommandException(message)
- }
-
protected fun checkConnected(action: String) {
- if (!plugin.storage.isConnected) error("Parcels cannot $action right now because of a database error")
+ if (!plugin.storage.isConnected) err("Parcels cannot $action right now because of a database error")
}
protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
@@ -35,7 +31,7 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
val limit = player.parcelLimit
if (numOwnedParcels >= limit) {
- error("You have enough plots for now")
+ err("You have enough plots for now")
}
}
@@ -65,10 +61,7 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
}
}
- protected fun err(message: String): Nothing = throw CommandException(message)
-
override fun getCoroutineContext() = plugin.coroutineContext
-
-
}
+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 9c3ca4f..79028a2 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdmin.kt
@@ -8,18 +8,19 @@ import io.dico.dicore.command.annotation.Flag
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.PlayerProfile
import io.dico.parcels2.Privilege
-import io.dico.parcels2.command.ParcelTarget.Companion.ID
-import io.dico.parcels2.command.ParcelTarget.Kind
+import io.dico.parcels2.command.ParcelTarget.TargetKind
+import io.dico.parcels2.resolved
class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
@Cmd("setowner")
@RequireParcelPrivilege(Privilege.ADMIN)
- fun ParcelScope.cmdSetowner(target: PlayerProfile): Any? {
- parcel.owner = target
+ suspend fun ParcelScope.cmdSetowner(@ProfileKind(ProfileKind.ANY) target: PlayerProfile): Any? {
+ val profile = target.resolved(plugin.storage, resolveToFake = true)!!
+ parcel.owner = profile
- val fakeString = if (target.isFake) " (fake)" else ""
- return "${target.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
+ val fakeString = if (profile.isFake) " (fake)" else ""
+ return "${profile.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
}
@Cmd("dispose")
@@ -43,7 +44,7 @@ class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
@Cmd("swap")
@RequireParcelPrivilege(Privilege.ADMIN)
fun ParcelScope.cmdSwap(context: ExecutionContext,
- @Kind(ID) target: ParcelTarget,
+ @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)
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
index 1bd42e8..541ea87 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt
@@ -9,16 +9,14 @@ 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.OfflinePlayer
-import org.bukkit.command.CommandSender
-import org.bukkit.entity.Player
class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
private val data
inline get() = plugin.globalPrivileges
private fun checkContext(context: ExecutionContext, owner: OfflinePlayer): OfflinePlayer {
+ checkConnected("have privileges changed")
val sender = context.sender
if (sender !== owner) {
Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
index b3b632f..6331b4c 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsDebug.kt
@@ -1,14 +1,17 @@
package io.dico.parcels2.command
import io.dico.dicore.command.*
-import io.dico.dicore.command.IContextFilter.Priority.*
+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.ParcelsPlugin
-import io.dico.parcels2.Privilege
+import io.dico.parcels2.*
import io.dico.parcels2.blockvisitor.RegionTraverser
-import io.dico.parcels2.doBlockOperation
+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
@@ -29,7 +32,7 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
if (worldName == "list") {
return Bukkit.getWorlds().joinToString("\n- ", "- ", "")
}
- val world = Bukkit.getWorld(worldName) ?: throw CommandException("World $worldName is not loaded")
+ val world = Bukkit.getWorld(worldName) ?: err("World $worldName is not loaded")
sender.teleport(world.spawnLocation)
return "Teleported you to $worldName spawn"
}
@@ -76,44 +79,64 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
blockData.javaClass.interfaces!!.contentToString()
}
- @Cmd("visitors")
- fun cmdVisitors(): Any? {
+ @Cmd("jobs")
+ fun cmdJobs(): Any? {
val workers = plugin.workDispatcher.workers
println(workers.map { it.job }.joinToString(separator = "\n"))
return "Task count: ${workers.size}"
}
- @Cmd("force_visitors")
- fun cmdForceVisitors(): Any? {
- val workers = plugin.workDispatcher.workers
- plugin.workDispatcher.completeAllTasks()
- return "Completed task count: ${workers.size}"
- }
-
- @Cmd("hasperm")
- fun cmdHasperm(sender: CommandSender, target: Player, permission: String): Any? {
- return target.hasPermission(permission).toString()
+ @Cmd("complete_jobs")
+ fun cmdCompleteJobs(): Any? = cmdJobs().also {
+ plugin.launch { plugin.workDispatcher.completeAllTasks() }
}
@Cmd("message")
@PreprocessArgs
fun cmdMessage(sender: CommandSender, message: String): Any? {
+ // testing @PreprocessArgs which merges "hello there" into a single argument
sender.sendMessage(message)
return null
}
+ @Cmd("hasperm")
+ fun cmdHasperm(target: Player, permission: String): Any? {
+ return target.hasPermission(permission).toString()
+ }
+
@Cmd("permissions")
- fun cmdPermissions(context: ExecutionContext, vararg address: String): Any? {
+ 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 permissions = getPermissionsOf(target)
- return permissions.joinToString(separator = "\n")
+ 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,
- path: Array<String> = emptyArray(),
- result: MutableList<String> = mutableListOf()): List<String> {
+ 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
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
index 67b873b..7f791cf 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsGeneral.kt
@@ -9,7 +9,7 @@ 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.Kind
+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
@@ -29,7 +29,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
checkParcelLimit(player, world)
val parcel = world.nextEmptyParcel()
- ?: error("This world is full, please ask an admin to upsize it")
+ ?: 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!"
@@ -58,7 +58,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
@RequireParameters(0)
suspend fun cmdHome(
player: Player,
- @Kind(ParcelTarget.OWNER_REAL) target: ParcelTarget
+ @TargetKind(TargetKind.OWNER_REAL) target: ParcelTarget
): Any? {
return cmdGoto(player, target)
}
@@ -66,7 +66,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
@Cmd("tp", aliases = ["teleport"])
suspend fun cmdTp(
player: Player,
- @Kind(ParcelTarget.ID) target: ParcelTarget
+ @TargetKind(TargetKind.ID) target: ParcelTarget
): Any? {
return cmdGoto(player, target)
}
@@ -74,17 +74,17 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
@Cmd("goto")
suspend fun cmdGoto(
player: Player,
- @Kind(ParcelTarget.ANY) target: ParcelTarget
+ @TargetKind(TargetKind.ANY) target: ParcelTarget
): Any? {
if (target is ParcelTarget.ByOwner) {
target.resolveOwner(plugin.storage)
if (!target.owner.matches(player) && !player.hasParcelHomeOthers) {
- error("You do not have permission to teleport to other people's parcels")
+ err("You do not have permission to teleport to other people's parcels")
}
}
val match = target.getParcelSuspend(plugin.storage)
- ?: error("The specified parcel could not be matched")
+ ?: err("The specified parcel could not be matched")
player.teleport(match.homeLocation)
return null
}
@@ -92,7 +92,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
@Cmd("goto_fake")
suspend fun cmdGotoFake(
player: Player,
- @Kind(ParcelTarget.OWNER_FAKE) target: ParcelTarget
+ @TargetKind(TargetKind.OWNER_FAKE) target: ParcelTarget
): Any? {
return cmdGoto(player, target)
}
@@ -105,7 +105,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
suspend fun ParcelScope.cmdClaim(player: Player): Any? {
checkConnected("be claimed")
parcel.owner.takeIf { !player.hasPermAdminManage }?.let {
- error(if (it.matches(player)) "You already own this parcel" else "This parcel is not available")
+ err(if (it.matches(player)) "You already own this parcel" else "This parcel is not available")
}
checkParcelLimit(player, world)
@@ -117,6 +117,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
@Desc("Unclaims this parcel")
@RequireParcelPrivilege(Privilege.OWNER)
fun ParcelScope.cmdUnclaim(player: Player): Any? {
+ checkConnected("be unclaimed")
parcel.dispose()
return "Your parcel has been disposed"
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
index f347f06..21910b1 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesLocal.kt
@@ -28,6 +28,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.OWNER)
suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
@@ -46,6 +47,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.OWNER)
suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
@@ -63,6 +65,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
@@ -83,6 +86,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
@@ -103,6 +107,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
@@ -123,6 +128,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
)
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
+ checkConnected("have privileges changed")
checkOwned(sender)
val key = toPrivilegeKey(player)
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index 40e5253..891988c 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -33,7 +33,7 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilde
)
group("interact", "i") {
- val command = ParcelOptionsInteractCommand(plugin.parcelProvider)
+ val command = ParcelOptionsInteractCommand(plugin)
Interactables.classesById.forEach {
addSubCommand(it.name, command)
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
index 5c38b06..1b61660 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt
@@ -4,11 +4,12 @@ import io.dico.dicore.command.*
import io.dico.dicore.command.parameter.type.ParameterTypes
import io.dico.parcels2.Interactables
import io.dico.parcels2.ParcelProvider
+import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.Privilege
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
-class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command() {
+class ParcelOptionsInteractCommand(val plugin: ParcelsPlugin) : Command() {
init {
setShortDescription("View and/or change the setting")
@@ -20,10 +21,12 @@ class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command
}
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 = parcelProvider.getParcelRequired(sender as Player,
+ val parcel = plugin.parcelProvider.getParcelRequired(sender as Player,
if (allowed == null) Privilege.DEFAULT else Privilege.CAN_MANAGE)
if (allowed == null) {
@@ -52,5 +55,3 @@ class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command
}
}
-
-private fun err(message: String): Nothing = throw CommandException(message) \ No newline at end of file
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
index 8beef7f..ae58f94 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt
@@ -3,8 +3,12 @@ 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.command.CommandSender
import org.bukkit.entity.Player
@@ -43,11 +47,27 @@ class ParcelParameterType(val parcelProvider: ParcelProvider) : ParameterType<Pa
}
-class ProfileParameterType : ParameterType<PlayerProfile, Void>(PlayerProfile::class.java) {
+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 = 4
+
+ 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
- override fun parse(parameter: Parameter<PlayerProfile, Void>, sender: CommandSender, buffer: ArgumentBuffer): PlayerProfile {
val input = buffer.next()
- return PlayerProfile.byName(input, allowReal = true, allowFake = true)
+ return PlayerProfile.byName(input, allowReal, allowFake)
}
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
index 8c0d718..2852ff0 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt
@@ -4,13 +4,20 @@ 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.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.Vec2i
import io.dico.parcels2.util.ext.floor
-import kotlinx.coroutines.CoroutineStart.UNDISPATCHED
-import kotlinx.coroutines.Deferred
-import kotlinx.coroutines.async
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
@@ -18,8 +25,6 @@ sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDef
abstract suspend fun getParcelSuspend(storage: Storage): Parcel?
- fun ParcelsPlugin.getParcelDeferred(): Deferred<Parcel?> = async(start = UNDISPATCHED) { getParcelSuspend(storage) }
-
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) }
@@ -61,29 +66,29 @@ sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDef
}
}
- companion object {
- 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
+ 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 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 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
- }
+ 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
- annotation class Kind(val kind: Int)
- private object Config : ParameterConfig<Kind, Int>(Kind::class.java) {
- override fun toParameterInfo(annotation: Kind): Int {
- return annotation.kind
+ override fun toParameterInfo(annotation: TargetKind): Int {
+ return annotation.kind
+ }
}
}
- class PType(val parcelProvider: ParcelProvider, val parcelAddress: SpecialCommandAddress? = null) : ParameterType<ParcelTarget, Int>(ParcelTarget::class.java, Config) {
+ 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()
diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
index 1c513f8..7ccb458 100644
--- a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
+++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt
@@ -219,7 +219,7 @@ class DefaultParcelGenerator(
skullBlock.type = Material.PLAYER_HEAD
val skull = skullBlock.state as Skull
if (owner is PlayerProfile.Real) {
- skull.owningPlayer = owner.playerUnchecked
+ skull.owningPlayer = Bukkit.getOfflinePlayer(owner.uuid)
} else {
skull.owner = owner.name
}
diff --git a/src/main/kotlin/io/dico/parcels2/listener/ListenerHelper.kt b/src/main/kotlin/io/dico/parcels2/listener/ListenerHelper.kt
deleted file mode 100644
index e8617fd..0000000
--- a/src/main/kotlin/io/dico/parcels2/listener/ListenerHelper.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.dico.parcels2.listener
-
-import io.dico.dicore.RegistratorListener
-import io.dico.parcels2.ParcelsPlugin
-import org.bukkit.event.Event
-
-interface HasPlugin {
- val plugin: ParcelsPlugin
-}
-
-inline fun <reified T : Event> HasPlugin.listener(crossinline block: suspend (T) -> Unit) = RegistratorListener<T> { event ->
-
-
-}
-
-
diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
index f838950..a62f569 100644
--- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
+++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt
@@ -60,7 +60,7 @@ class ParcelListeners(
val user = event.player
if (user.hasPermBanBypass) return@l
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
- if (!parcel.canEnter(user)) {
+ if (!parcel.canEnterFast(user)) {
parcelProvider.getParcelAt(event.from)?.also {
user.teleport(it.homeLocation)
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
diff --git a/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt b/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt
new file mode 100644
index 0000000..d6837bd
--- /dev/null
+++ b/src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt
@@ -0,0 +1,12 @@
+package io.dico.parcels2.util
+
+import io.dico.parcels2.util.ext.isValid
+import org.bukkit.Bukkit
+import org.bukkit.OfflinePlayer
+import java.util.UUID
+
+fun getPlayerName(uuid: UUID): String? = getOfflinePlayer(uuid)?.name
+
+fun getOfflinePlayer(uuid: UUID): OfflinePlayer? = Bukkit.getOfflinePlayer(uuid).takeIf { it.isValid }
+
+fun getOfflinePlayer(name: String): OfflinePlayer? = Bukkit.getOfflinePlayer(name).takeIf { it.isValid }
diff --git a/src/main/kotlin/io/dico/parcels2/util/UUIDUtil.kt b/src/main/kotlin/io/dico/parcels2/util/UUIDUtil.kt
deleted file mode 100644
index 1398037..0000000
--- a/src/main/kotlin/io/dico/parcels2/util/UUIDUtil.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.dico.parcels2.util
-
-import io.dico.parcels2.util.ext.isValid
-import org.bukkit.Bukkit
-import java.nio.ByteBuffer
-import java.util.UUID
-
-const val PLAYER_NAME_PLACEHOLDER = ":unknown_name:"
-
-fun getPlayerName(uuid: UUID): String? {
- return Bukkit.getOfflinePlayer(uuid)?.takeIf { it.isValid }?.name
-}
-
-
diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
index e4c2b4c..4df4d52 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/ext/Misc.kt
@@ -2,7 +2,10 @@ package io.dico.parcels2.util.ext
import io.dico.dicore.Formatting
import io.dico.parcels2.logger
+import org.bukkit.Bukkit
+import org.bukkit.OfflinePlayer
import java.io.File
+import java.util.UUID
fun File.tryCreate(): Boolean {
if (exists()) {
diff --git a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt
index 1875ff8..a7f21c5 100644
--- a/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt
+++ b/src/main/kotlin/io/dico/parcels2/util/ext/Player.kt
@@ -52,4 +52,6 @@ fun Player.sendParcelMessage(except: Boolean = false, nopermit: Boolean = false,
} else {
sendMessage(prefix + Formatting.translateChars('&', message))
}
-} \ No newline at end of file
+}
+
+const val PLAYER_NAME_PLACEHOLDER = ":unknown_name:"