Tweaks
This commit is contained in:
@@ -3,13 +3,11 @@
|
|||||||
package io.dico.parcels2
|
package io.dico.parcels2
|
||||||
|
|
||||||
import io.dico.parcels2.storage.Storage
|
import io.dico.parcels2.storage.Storage
|
||||||
import io.dico.parcels2.util.PLAYER_NAME_PLACEHOLDER
|
import io.dico.parcels2.util.ext.PLAYER_NAME_PLACEHOLDER
|
||||||
import io.dico.parcels2.util.getPlayerName
|
|
||||||
import io.dico.parcels2.util.ext.isValid
|
import io.dico.parcels2.util.ext.isValid
|
||||||
import io.dico.parcels2.util.ext.uuid
|
import io.dico.parcels2.util.ext.uuid
|
||||||
import kotlinx.coroutines.Deferred
|
import io.dico.parcels2.util.getOfflinePlayer
|
||||||
import kotlinx.coroutines.Unconfined
|
import io.dico.parcels2.util.getPlayerName
|
||||||
import kotlinx.coroutines.async
|
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.OfflinePlayer
|
import org.bukkit.OfflinePlayer
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -70,8 +68,7 @@ interface PlayerProfile {
|
|||||||
|
|
||||||
if (input == Star.name) return Star
|
if (input == Star.name) return Star
|
||||||
|
|
||||||
return Bukkit.getOfflinePlayer(input).takeIf { it.isValid }?.let { PlayerProfile(it) }
|
return getOfflinePlayer(input)?.let { PlayerProfile(it) } ?: Unresolved(input)
|
||||||
?: Unresolved(input)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +80,7 @@ interface PlayerProfile {
|
|||||||
override val notNullName: String
|
override val notNullName: String
|
||||||
get() = nameOrBukkitName ?: PLAYER_NAME_PLACEHOLDER
|
get() = nameOrBukkitName ?: PLAYER_NAME_PLACEHOLDER
|
||||||
|
|
||||||
val player: OfflinePlayer? get() = Bukkit.getOfflinePlayer(uuid).takeIf { it.isValid }
|
val player: OfflinePlayer? get() = getOfflinePlayer(uuid)
|
||||||
val playerUnchecked: OfflinePlayer get() = Bukkit.getOfflinePlayer(uuid)
|
|
||||||
|
|
||||||
override fun matches(player: OfflinePlayer, allowNameMatch: Boolean): Boolean {
|
override fun matches(player: OfflinePlayer, allowNameMatch: Boolean): Boolean {
|
||||||
return uuid == player.uuid || (allowNameMatch && name?.let { it == player.name } == true)
|
return uuid == player.uuid || (allowNameMatch && name?.let { it == player.name } == true)
|
||||||
@@ -147,10 +143,6 @@ interface PlayerProfile {
|
|||||||
return other is Unresolved && name == other.name
|
return other is Unresolved && name == other.name
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryResolve(storage: Storage): Deferred<Real?> {
|
|
||||||
return async(Unconfined) { tryResolveSuspendedly(storage) }
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun tryResolveSuspendedly(storage: Storage): Real? {
|
suspend fun tryResolveSuspendedly(storage: Storage): Real? {
|
||||||
return storage.getPlayerUuidForName(name).await()?.let { resolve(it) }
|
return storage.getPlayerUuidForName(name).await()?.let { resolve(it) }
|
||||||
}
|
}
|
||||||
@@ -178,120 +170,9 @@ interface PlayerProfile {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
* 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ data class TickWorktimeOptions(var workTime: Int, var tickInterval: Int)
|
|||||||
interface WorkDispatcher {
|
interface WorkDispatcher {
|
||||||
/**
|
/**
|
||||||
* Submit a [task] that should be run synchronously, but limited such that it does not stall the server
|
* 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
|
fun dispatch(task: WorkerTask): Worker
|
||||||
|
|
||||||
@@ -89,11 +88,6 @@ interface Worker : WorkerAndScopeMembersUnion {
|
|||||||
* Await completion of this worker
|
* Await completion of this worker
|
||||||
*/
|
*/
|
||||||
suspend fun awaitCompletion()
|
suspend fun awaitCompletion()
|
||||||
|
|
||||||
/**
|
|
||||||
* An object attached to this worker
|
|
||||||
*/
|
|
||||||
//val attachment: Any?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WorkerScope : WorkerAndScopeMembersUnion {
|
interface WorkerScope : WorkerAndScopeMembersUnion {
|
||||||
@@ -114,7 +108,7 @@ interface WorkerScope : WorkerAndScopeMembersUnion {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a [WorkerScope] that is responsible for [portion] part of the progress
|
* 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
|
fun delegateWork(portion: Double = -1.0): WorkerScope
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,8 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
|
|||||||
return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
|
return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun error(message: String): Nothing {
|
|
||||||
throw CommandException(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun checkConnected(action: String) {
|
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) {
|
protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
|
||||||
@@ -35,7 +31,7 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei
|
|||||||
|
|
||||||
val limit = player.parcelLimit
|
val limit = player.parcelLimit
|
||||||
if (numOwnedParcels >= limit) {
|
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
|
override fun getCoroutineContext() = plugin.coroutineContext
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun err(message: String): Nothing = throw CommandException(message)
|
||||||
@@ -8,18 +8,19 @@ import io.dico.dicore.command.annotation.Flag
|
|||||||
import io.dico.parcels2.ParcelsPlugin
|
import io.dico.parcels2.ParcelsPlugin
|
||||||
import io.dico.parcels2.PlayerProfile
|
import io.dico.parcels2.PlayerProfile
|
||||||
import io.dico.parcels2.Privilege
|
import io.dico.parcels2.Privilege
|
||||||
import io.dico.parcels2.command.ParcelTarget.Companion.ID
|
import io.dico.parcels2.command.ParcelTarget.TargetKind
|
||||||
import io.dico.parcels2.command.ParcelTarget.Kind
|
import io.dico.parcels2.resolved
|
||||||
|
|
||||||
class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||||
|
|
||||||
@Cmd("setowner")
|
@Cmd("setowner")
|
||||||
@RequireParcelPrivilege(Privilege.ADMIN)
|
@RequireParcelPrivilege(Privilege.ADMIN)
|
||||||
fun ParcelScope.cmdSetowner(target: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdSetowner(@ProfileKind(ProfileKind.ANY) target: PlayerProfile): Any? {
|
||||||
parcel.owner = target
|
val profile = target.resolved(plugin.storage, resolveToFake = true)!!
|
||||||
|
parcel.owner = profile
|
||||||
|
|
||||||
val fakeString = if (target.isFake) " (fake)" else ""
|
val fakeString = if (profile.isFake) " (fake)" else ""
|
||||||
return "${target.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
|
return "${profile.notNullName}$fakeString is the new owner of (${parcel.id.idString})"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cmd("dispose")
|
@Cmd("dispose")
|
||||||
@@ -43,7 +44,7 @@ class CommandsAdmin(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
|||||||
@Cmd("swap")
|
@Cmd("swap")
|
||||||
@RequireParcelPrivilege(Privilege.ADMIN)
|
@RequireParcelPrivilege(Privilege.ADMIN)
|
||||||
fun ParcelScope.cmdSwap(context: ExecutionContext,
|
fun ParcelScope.cmdSwap(context: ExecutionContext,
|
||||||
@Kind(ID) target: ParcelTarget,
|
@TargetKind(TargetKind.ID) target: ParcelTarget,
|
||||||
@Flag sure: Boolean): Any? {
|
@Flag sure: Boolean): Any? {
|
||||||
Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
|
Validate.isTrue(!parcel.hasBlockVisitors, "A process is already running in this parcel")
|
||||||
if (!sure) return areYouSureMessage(context)
|
if (!sure) return areYouSureMessage(context)
|
||||||
|
|||||||
@@ -9,16 +9,14 @@ import io.dico.dicore.command.annotation.Desc
|
|||||||
import io.dico.parcels2.*
|
import io.dico.parcels2.*
|
||||||
import io.dico.parcels2.PrivilegeChangeResult.*
|
import io.dico.parcels2.PrivilegeChangeResult.*
|
||||||
import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
|
import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE
|
||||||
import io.dico.parcels2.util.ext.hasPermAdminManage
|
|
||||||
import org.bukkit.OfflinePlayer
|
import org.bukkit.OfflinePlayer
|
||||||
import org.bukkit.command.CommandSender
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
|
|
||||||
class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
||||||
private val data
|
private val data
|
||||||
inline get() = plugin.globalPrivileges
|
inline get() = plugin.globalPrivileges
|
||||||
|
|
||||||
private fun checkContext(context: ExecutionContext, owner: OfflinePlayer): OfflinePlayer {
|
private fun checkContext(context: ExecutionContext, owner: OfflinePlayer): OfflinePlayer {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
val sender = context.sender
|
val sender = context.sender
|
||||||
if (sender !== owner) {
|
if (sender !== owner) {
|
||||||
Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
|
Validate.isAuthorized(sender, PERM_ADMIN_MANAGE)
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package io.dico.parcels2.command
|
package io.dico.parcels2.command
|
||||||
|
|
||||||
import io.dico.dicore.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.Cmd
|
||||||
import io.dico.dicore.command.annotation.PreprocessArgs
|
import io.dico.dicore.command.annotation.PreprocessArgs
|
||||||
|
import io.dico.dicore.command.annotation.RequireParameters
|
||||||
import io.dico.dicore.command.parameter.ArgumentBuffer
|
import io.dico.dicore.command.parameter.ArgumentBuffer
|
||||||
import io.dico.parcels2.ParcelsPlugin
|
import io.dico.parcels2.*
|
||||||
import io.dico.parcels2.Privilege
|
|
||||||
import io.dico.parcels2.blockvisitor.RegionTraverser
|
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.Bukkit
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.block.BlockFace
|
import org.bukkit.block.BlockFace
|
||||||
@@ -29,7 +32,7 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
|||||||
if (worldName == "list") {
|
if (worldName == "list") {
|
||||||
return Bukkit.getWorlds().joinToString("\n- ", "- ", "")
|
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)
|
sender.teleport(world.spawnLocation)
|
||||||
return "Teleported you to $worldName spawn"
|
return "Teleported you to $worldName spawn"
|
||||||
}
|
}
|
||||||
@@ -76,44 +79,64 @@ class CommandsDebug(plugin: ParcelsPlugin) : AbstractParcelCommands(plugin) {
|
|||||||
blockData.javaClass.interfaces!!.contentToString()
|
blockData.javaClass.interfaces!!.contentToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cmd("visitors")
|
@Cmd("jobs")
|
||||||
fun cmdVisitors(): Any? {
|
fun cmdJobs(): Any? {
|
||||||
val workers = plugin.workDispatcher.workers
|
val workers = plugin.workDispatcher.workers
|
||||||
println(workers.map { it.job }.joinToString(separator = "\n"))
|
println(workers.map { it.job }.joinToString(separator = "\n"))
|
||||||
return "Task count: ${workers.size}"
|
return "Task count: ${workers.size}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cmd("force_visitors")
|
@Cmd("complete_jobs")
|
||||||
fun cmdForceVisitors(): Any? {
|
fun cmdCompleteJobs(): Any? = cmdJobs().also {
|
||||||
val workers = plugin.workDispatcher.workers
|
plugin.launch { plugin.workDispatcher.completeAllTasks() }
|
||||||
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("message")
|
@Cmd("message")
|
||||||
@PreprocessArgs
|
@PreprocessArgs
|
||||||
fun cmdMessage(sender: CommandSender, message: String): Any? {
|
fun cmdMessage(sender: CommandSender, message: String): Any? {
|
||||||
|
// testing @PreprocessArgs which merges "hello there" into a single argument
|
||||||
sender.sendMessage(message)
|
sender.sendMessage(message)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cmd("permissions")
|
@Cmd("hasperm")
|
||||||
fun cmdPermissions(context: ExecutionContext, vararg address: String): Any? {
|
fun cmdHasperm(target: Player, permission: String): Any? {
|
||||||
val target = context.address.dispatcherForTree.getDeepChild(ArgumentBuffer(address))
|
return target.hasPermission(permission).toString()
|
||||||
Validate.isTrue(target.depth == address.size && target.hasCommand(), "Not found: /${address.joinToString(separator = " ")}")
|
|
||||||
|
|
||||||
val permissions = getPermissionsOf(target)
|
|
||||||
return permissions.joinToString(separator = "\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPermissionsOf(address: ICommandAddress,
|
@Cmd("permissions")
|
||||||
path: Array<String> = emptyArray(),
|
fun cmdPermissions(context: ExecutionContext, of: Player, vararg address: String): Any? {
|
||||||
result: MutableList<String> = mutableListOf()): List<String> {
|
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
|
val command = address.command ?: return result
|
||||||
|
|
||||||
var inherited = false
|
var inherited = false
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import io.dico.dicore.command.annotation.RequireParameters
|
|||||||
import io.dico.parcels2.ParcelsPlugin
|
import io.dico.parcels2.ParcelsPlugin
|
||||||
import io.dico.parcels2.PlayerProfile
|
import io.dico.parcels2.PlayerProfile
|
||||||
import io.dico.parcels2.Privilege
|
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.hasParcelHomeOthers
|
||||||
import io.dico.parcels2.util.ext.hasPermAdminManage
|
import io.dico.parcels2.util.ext.hasPermAdminManage
|
||||||
import io.dico.parcels2.util.ext.uuid
|
import io.dico.parcels2.util.ext.uuid
|
||||||
@@ -29,7 +29,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
checkParcelLimit(player, world)
|
checkParcelLimit(player, world)
|
||||||
|
|
||||||
val parcel = world.nextEmptyParcel()
|
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)
|
parcel.owner = PlayerProfile(uuid = player.uuid)
|
||||||
player.teleport(parcel.homeLocation)
|
player.teleport(parcel.homeLocation)
|
||||||
return "Enjoy your new parcel!"
|
return "Enjoy your new parcel!"
|
||||||
@@ -58,7 +58,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
@RequireParameters(0)
|
@RequireParameters(0)
|
||||||
suspend fun cmdHome(
|
suspend fun cmdHome(
|
||||||
player: Player,
|
player: Player,
|
||||||
@Kind(ParcelTarget.OWNER_REAL) target: ParcelTarget
|
@TargetKind(TargetKind.OWNER_REAL) target: ParcelTarget
|
||||||
): Any? {
|
): Any? {
|
||||||
return cmdGoto(player, target)
|
return cmdGoto(player, target)
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
@Cmd("tp", aliases = ["teleport"])
|
@Cmd("tp", aliases = ["teleport"])
|
||||||
suspend fun cmdTp(
|
suspend fun cmdTp(
|
||||||
player: Player,
|
player: Player,
|
||||||
@Kind(ParcelTarget.ID) target: ParcelTarget
|
@TargetKind(TargetKind.ID) target: ParcelTarget
|
||||||
): Any? {
|
): Any? {
|
||||||
return cmdGoto(player, target)
|
return cmdGoto(player, target)
|
||||||
}
|
}
|
||||||
@@ -74,17 +74,17 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
@Cmd("goto")
|
@Cmd("goto")
|
||||||
suspend fun cmdGoto(
|
suspend fun cmdGoto(
|
||||||
player: Player,
|
player: Player,
|
||||||
@Kind(ParcelTarget.ANY) target: ParcelTarget
|
@TargetKind(TargetKind.ANY) target: ParcelTarget
|
||||||
): Any? {
|
): Any? {
|
||||||
if (target is ParcelTarget.ByOwner) {
|
if (target is ParcelTarget.ByOwner) {
|
||||||
target.resolveOwner(plugin.storage)
|
target.resolveOwner(plugin.storage)
|
||||||
if (!target.owner.matches(player) && !player.hasParcelHomeOthers) {
|
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)
|
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)
|
player.teleport(match.homeLocation)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
@Cmd("goto_fake")
|
@Cmd("goto_fake")
|
||||||
suspend fun cmdGotoFake(
|
suspend fun cmdGotoFake(
|
||||||
player: Player,
|
player: Player,
|
||||||
@Kind(ParcelTarget.OWNER_FAKE) target: ParcelTarget
|
@TargetKind(TargetKind.OWNER_FAKE) target: ParcelTarget
|
||||||
): Any? {
|
): Any? {
|
||||||
return cmdGoto(player, target)
|
return cmdGoto(player, target)
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
suspend fun ParcelScope.cmdClaim(player: Player): Any? {
|
suspend fun ParcelScope.cmdClaim(player: Player): Any? {
|
||||||
checkConnected("be claimed")
|
checkConnected("be claimed")
|
||||||
parcel.owner.takeIf { !player.hasPermAdminManage }?.let {
|
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)
|
checkParcelLimit(player, world)
|
||||||
@@ -117,6 +117,7 @@ class CommandsGeneral(plugin: ParcelsPlugin, parent: SpecialCommandAddress) : Ab
|
|||||||
@Desc("Unclaims this parcel")
|
@Desc("Unclaims this parcel")
|
||||||
@RequireParcelPrivilege(Privilege.OWNER)
|
@RequireParcelPrivilege(Privilege.OWNER)
|
||||||
fun ParcelScope.cmdUnclaim(player: Player): Any? {
|
fun ParcelScope.cmdUnclaim(player: Player): Any? {
|
||||||
|
checkConnected("be unclaimed")
|
||||||
parcel.dispose()
|
parcel.dispose()
|
||||||
return "Your parcel has been disposed"
|
return "Your parcel has been disposed"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.OWNER)
|
@RequireParcelPrivilege(Privilege.OWNER)
|
||||||
suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdEntrust(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
@@ -46,6 +47,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.OWNER)
|
@RequireParcelPrivilege(Privilege.OWNER)
|
||||||
suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdDistrust(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
@@ -63,6 +65,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
||||||
suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdAllow(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
@@ -83,6 +86,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
||||||
suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdDisallow(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
@@ -103,6 +107,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
||||||
suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdBan(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
@@ -123,6 +128,7 @@ class CommandsPrivilegesLocal(plugin: ParcelsPlugin) : AbstractParcelCommands(pl
|
|||||||
)
|
)
|
||||||
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
@RequireParcelPrivilege(Privilege.CAN_MANAGE)
|
||||||
suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
|
suspend fun ParcelScope.cmdUnban(sender: Player, player: PlayerProfile): Any? {
|
||||||
|
checkConnected("have privileges changed")
|
||||||
checkOwned(sender)
|
checkOwned(sender)
|
||||||
|
|
||||||
val key = toPrivilegeKey(player)
|
val key = toPrivilegeKey(player)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilde
|
|||||||
)
|
)
|
||||||
|
|
||||||
group("interact", "i") {
|
group("interact", "i") {
|
||||||
val command = ParcelOptionsInteractCommand(plugin.parcelProvider)
|
val command = ParcelOptionsInteractCommand(plugin)
|
||||||
Interactables.classesById.forEach {
|
Interactables.classesById.forEach {
|
||||||
addSubCommand(it.name, command)
|
addSubCommand(it.name, command)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import io.dico.dicore.command.*
|
|||||||
import io.dico.dicore.command.parameter.type.ParameterTypes
|
import io.dico.dicore.command.parameter.type.ParameterTypes
|
||||||
import io.dico.parcels2.Interactables
|
import io.dico.parcels2.Interactables
|
||||||
import io.dico.parcels2.ParcelProvider
|
import io.dico.parcels2.ParcelProvider
|
||||||
|
import io.dico.parcels2.ParcelsPlugin
|
||||||
import io.dico.parcels2.Privilege
|
import io.dico.parcels2.Privilege
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command() {
|
class ParcelOptionsInteractCommand(val plugin: ParcelsPlugin) : Command() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setShortDescription("View and/or change the setting")
|
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? {
|
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 interactableClass = Interactables[context.address.mainKey]
|
||||||
val allowed: Boolean? = context.get("allowed")
|
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) Privilege.DEFAULT else Privilege.CAN_MANAGE)
|
||||||
|
|
||||||
if (allowed == null) {
|
if (allowed == null) {
|
||||||
@@ -52,5 +55,3 @@ class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun err(message: String): Nothing = throw CommandException(message)
|
|
||||||
@@ -3,8 +3,12 @@ package io.dico.parcels2.command
|
|||||||
import io.dico.dicore.command.CommandException
|
import io.dico.dicore.command.CommandException
|
||||||
import io.dico.dicore.command.parameter.ArgumentBuffer
|
import io.dico.dicore.command.parameter.ArgumentBuffer
|
||||||
import io.dico.dicore.command.parameter.Parameter
|
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.dicore.command.parameter.type.ParameterType
|
||||||
import io.dico.parcels2.*
|
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.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
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()
|
val input = buffer.next()
|
||||||
return PlayerProfile.byName(input, allowReal = true, allowFake = true)
|
return PlayerProfile.byName(input, allowReal, allowFake)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,20 @@ import io.dico.dicore.command.parameter.ArgumentBuffer
|
|||||||
import io.dico.dicore.command.parameter.Parameter
|
import io.dico.dicore.command.parameter.Parameter
|
||||||
import io.dico.dicore.command.parameter.type.ParameterConfig
|
import io.dico.dicore.command.parameter.type.ParameterConfig
|
||||||
import io.dico.dicore.command.parameter.type.ParameterType
|
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.storage.Storage
|
||||||
import io.dico.parcels2.util.Vec2i
|
import io.dico.parcels2.util.Vec2i
|
||||||
import io.dico.parcels2.util.ext.floor
|
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.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
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?
|
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) {
|
class ByID(world: ParcelWorld, val id: Vec2i?, parsedKind: Int, isDefault: Boolean) : ParcelTarget(world, parsedKind, isDefault) {
|
||||||
override suspend fun getParcelSuspend(storage: Storage): Parcel? = getParcel()
|
override suspend fun getParcelSuspend(storage: Storage): Parcel? = getParcel()
|
||||||
fun getParcel() = id?.let { world.getParcelById(it) }
|
fun getParcel() = id?.let { world.getParcelById(it) }
|
||||||
@@ -61,29 +66,29 @@ sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDef
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
annotation class TargetKind(val kind: Int) {
|
||||||
const val ID = 1 // ID
|
companion object : ParameterConfig<TargetKind, Int>(TargetKind::class.java) {
|
||||||
const val OWNER_REAL = 2 // an owner backed by a UUID
|
const val ID = 1 // ID
|
||||||
const val OWNER_FAKE = 4 // an owner not backed by a UUID
|
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 OWNER = OWNER_REAL or OWNER_FAKE // any owner
|
||||||
const val ANY = ID or OWNER_REAL or OWNER_FAKE // any
|
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 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
|
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
|
// instead of parcel that the player is in
|
||||||
}
|
|
||||||
|
|
||||||
annotation class Kind(val kind: Int)
|
override fun toParameterInfo(annotation: TargetKind): Int {
|
||||||
private object Config : ParameterConfig<Kind, Int>(Kind::class.java) {
|
return annotation.kind
|
||||||
override fun toParameterInfo(annotation: Kind): 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 {
|
override fun parse(parameter: Parameter<ParcelTarget, Int>, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget {
|
||||||
var input = buffer.next()
|
var input = buffer.next()
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ class DefaultParcelGenerator(
|
|||||||
skullBlock.type = Material.PLAYER_HEAD
|
skullBlock.type = Material.PLAYER_HEAD
|
||||||
val skull = skullBlock.state as Skull
|
val skull = skullBlock.state as Skull
|
||||||
if (owner is PlayerProfile.Real) {
|
if (owner is PlayerProfile.Real) {
|
||||||
skull.owningPlayer = owner.playerUnchecked
|
skull.owningPlayer = Bukkit.getOfflinePlayer(owner.uuid)
|
||||||
} else {
|
} else {
|
||||||
skull.owner = owner.name
|
skull.owner = owner.name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ->
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class ParcelListeners(
|
|||||||
val user = event.player
|
val user = event.player
|
||||||
if (user.hasPermBanBypass) return@l
|
if (user.hasPermBanBypass) return@l
|
||||||
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
|
val parcel = parcelProvider.getParcelAt(event.to) ?: return@l
|
||||||
if (!parcel.canEnter(user)) {
|
if (!parcel.canEnterFast(user)) {
|
||||||
parcelProvider.getParcelAt(event.from)?.also {
|
parcelProvider.getParcelAt(event.from)?.also {
|
||||||
user.teleport(it.homeLocation)
|
user.teleport(it.homeLocation)
|
||||||
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
|
user.sendParcelMessage(nopermit = true, message = "You are banned from this parcel")
|
||||||
|
|||||||
12
src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt
Normal file
12
src/main/kotlin/io/dico/parcels2/util/BukkitUtil.kt
Normal file
@@ -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 }
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2,7 +2,10 @@ package io.dico.parcels2.util.ext
|
|||||||
|
|
||||||
import io.dico.dicore.Formatting
|
import io.dico.dicore.Formatting
|
||||||
import io.dico.parcels2.logger
|
import io.dico.parcels2.logger
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.OfflinePlayer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
fun File.tryCreate(): Boolean {
|
fun File.tryCreate(): Boolean {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
|
|||||||
@@ -53,3 +53,5 @@ fun Player.sendParcelMessage(except: Boolean = false, nopermit: Boolean = false,
|
|||||||
sendMessage(prefix + Formatting.translateChars('&', message))
|
sendMessage(prefix + Formatting.translateChars('&', message))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const val PLAYER_NAME_PLACEHOLDER = ":unknown_name:"
|
||||||
|
|||||||
Reference in New Issue
Block a user