summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt
blob: eaa9f57ca53547c976b69747d1f1159ede7f9454 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package io.dico.parcels2.command

import io.dico.dicore.command.*
import io.dico.dicore.command.registration.reflect.ICommandInterceptor
import io.dico.dicore.command.registration.reflect.ICommandReceiver
import io.dico.parcels2.*
import io.dico.parcels2.PlayerProfile.Real
import io.dico.parcels2.PlayerProfile.Unresolved
import io.dico.parcels2.util.ext.hasPermAdminManage
import io.dico.parcels2.util.ext.parcelLimit
import org.bukkit.entity.Player
import org.bukkit.plugin.Plugin
import java.lang.reflect.Method

abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandInterceptor {

    override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver {
        return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName)
    }

    override fun getCoroutineContext(context: ExecutionContext?, target: Method?, cmdName: String?): Any {
        return plugin.coroutineContext
    }

    protected fun checkConnected(action: String) {
        if (!plugin.storage.isConnected) err("Parcels cannot $action right now because of a database error")
    }

    protected suspend fun checkParcelLimit(player: Player, world: ParcelWorld) {
        if (player.hasPermAdminManage) return
        val numOwnedParcels = plugin.storage.getOwnedParcels(PlayerProfile(player)).await()
            .filter { it.worldId.equals(world.id) }.size

        val limit = player.parcelLimit
        if (numOwnedParcels >= limit) {
            err("You have enough plots for now")
        }
    }

    protected suspend fun toPrivilegeKey(profile: PlayerProfile): PrivilegeKey = when (profile) {
        is Real -> profile
        is Unresolved -> profile.tryResolveSuspendedly(plugin.storage)
            ?: throw CommandException()
        else -> throw CommandException()
    }

    protected fun areYouSureMessage(context: ExecutionContext): String {
        val command = (context.route + context.original).joinToString(" ") + " -sure"
        return "Are you sure? You cannot undo this action!\n" +
            "Run \"/$command\" if you want to go through with this."
    }

    protected fun Job.reportProgressUpdates(context: ExecutionContext, action: String): Job =
        onProgressUpdate(1000, 1000) { progress, elapsedTime ->
            val alt = context.getFormat(EMessageType.NUMBER)
            val main = context.getFormat(EMessageType.INFORMATIVE)
            context.sendMessage(
                EMessageType.INFORMATIVE, false, "$action progress: $alt%.02f$main%%, $alt%.2f${main}s elapsed"
                    .format(progress * 100, elapsedTime / 1000.0)
            )
        }
}

fun err(message: String): Nothing = throw CommandException(message)