aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/commands/HelpCommand.kt
blob: 3500b00256cb24bf1fd61f9e6a5657f28d06d595 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package at.hannibal2.skyhanni.features.commands

import at.hannibal2.skyhanni.config.commands.Commands
import at.hannibal2.skyhanni.utils.StringUtils.splitLines
import at.hannibal2.skyhanni.utils.chat.Text
import at.hannibal2.skyhanni.utils.chat.Text.asComponent
import at.hannibal2.skyhanni.utils.chat.Text.center
import at.hannibal2.skyhanni.utils.chat.Text.fitToChat
import at.hannibal2.skyhanni.utils.chat.Text.hover
import at.hannibal2.skyhanni.utils.chat.Text.onClick
import at.hannibal2.skyhanni.utils.chat.Text.send
import at.hannibal2.skyhanni.utils.chat.Text.style
import at.hannibal2.skyhanni.utils.chat.Text.suggest
import net.minecraft.util.EnumChatFormatting
import net.minecraft.util.IChatComponent

object HelpCommand {

    private const val COMMANDS_PER_PAGE = 15
    private const val HELP_ID = -6457563

    private fun createDivider() = Text.HYPHEN.fitToChat().style {
        strikethrough = true
        color = EnumChatFormatting.BLUE
    }

    private fun createCommandEntry(command: Commands.CommandInfo): IChatComponent {
        val category = command.category
        val color = category.color
        val description = command.description.splitLines(200).replace("§r", "§7")
        val categoryDescription = category.description.splitLines(200).replace("§r", "§7")

        return Text.text("§7 - $color${command.name}") {
            this.hover = Text.multiline(
                "§e/${command.name}",
                if (description.isNotEmpty()) description.prependIndent("  ") else null,
                "",
                "$color§l${category.categoryName}",
                categoryDescription.prependIndent("  ")
            )
            this.suggest = "/${command.name}"
        }
    }

    private fun showPage(
        page: Int,
        search: String,
        commands: List<Commands.CommandInfo>
    ) {
        val filtered = commands.filter {
            it.name.contains(search, ignoreCase = true) || it.description.contains(search, ignoreCase = true)
        }
        val maxPage = filtered.size / COMMANDS_PER_PAGE + 1
        val page = page.coerceIn(1, maxPage)
        val title = if (search.isEmpty()) "§6SkyHanni Commands" else "§6SkyHanni Commands matching '$search'"

        val text = mutableListOf<IChatComponent>()

        text.add(createDivider())
        text.add(title.asComponent().center())
        text.add(Text.join(
            if (page > 1) "§6§l<<".asComponent {
                this.hover = "§eClick to view page ${page - 1}".asComponent()
                this.onClick { showPage(page - 1, search, commands) }
            } else null,
            " ",
            "§6(Page $page of $maxPage)",
            " ",
            if (page < maxPage) "§6§l>>".asComponent {
                this.hover = "§eClick to view page ${page + 1}".asComponent()
                this.onClick { showPage(page + 1, search, commands) }
            } else null
        ).center())
        text.add(createDivider())

        if (filtered.isEmpty()) {
            text.add(Text.EMPTY)
            text.add("§cNo reminders found.".asComponent().center())
            text.add(Text.EMPTY)
        } else {
            val start = (page - 1) * COMMANDS_PER_PAGE
            val end = (page * COMMANDS_PER_PAGE).coerceAtMost(filtered.size)
            for (i in start until end) {
                text.add(createCommandEntry(filtered[i]))
            }
        }

        text.add(createDivider())

        Text.multiline(text).send(HELP_ID)
    }

    fun onCommand(args: Array<String>, commands: List<Commands.CommandInfo>) {
        val page: Int
        val search: String
        if (args.firstOrNull() == "-p") {
            page = args.getOrNull(1)?.toIntOrNull() ?: 1
            search = args.drop(2).joinToString(" ")
        } else {
            page = 1
            search = args.joinToString(" ")
        }
        showPage(page, search, commands)
    }
}