aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/repo/ItemNameLookup.kt
blob: 4bdf616c7f519401e0f3a0cec67ee6d715baee9f (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
/*
 * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

package moe.nea.firmament.repo

import io.github.moulberry.repo.IReloadable
import io.github.moulberry.repo.NEURepository
import io.github.moulberry.repo.data.NEUItem
import java.util.NavigableMap
import java.util.TreeMap
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.removeColorCodes
import moe.nea.firmament.util.skyblockId

object ItemNameLookup : IReloadable {

    fun getItemNameChunks(name: String): Set<String> {
        return name.removeColorCodes().split(" ").filterTo(mutableSetOf()) { it.isNotBlank() }
    }

    var nameMap: NavigableMap<String, out Set<SkyblockId>> = TreeMap()

    override fun reload(repository: NEURepository) {
        val nameMap = TreeMap<String, MutableSet<SkyblockId>>()
        repository.items.items.values.forEach { item ->
            getAllNamesForItem(item).forEach { name ->
                val chunks = getItemNameChunks(name)
                chunks.forEach { chunk ->
                    val set = nameMap.getOrPut(chunk, ::mutableSetOf)
                    set.add(item.skyblockId)
                }
            }
        }
        this.nameMap = nameMap
    }

    fun getAllNamesForItem(item: NEUItem): Set<String> {
        val names = mutableSetOf<String>()
        names.add(item.displayName)
        if (item.displayName.contains("Enchanted Book")) {
            val enchantName = item.lore.firstOrNull()
            if (enchantName != null) {
                names.add(enchantName)
            }
        }
        return names
    }

    fun findItemCandidatesByName(name: String): MutableSet<SkyblockId> {
        val candidates = mutableSetOf<SkyblockId>()
        for (chunk in getItemNameChunks(name)) {
            val set = nameMap[chunk] ?: emptySet()
            candidates.addAll(set)
        }
        return candidates
    }


    fun guessItemByName(
        /**
         * The display name of the item. Color codes will be ignored.
         */
        name: String,
        /**
         * Whether the [name] may contain other text, such as reforges, master stars and such.
         */
        mayBeMangled: Boolean
    ): SkyblockId? {
        val cleanName = name.removeColorCodes()
        return findBestItemFromCandidates(
            findItemCandidatesByName(cleanName),
            cleanName,
            true
        )
    }

    fun findBestItemFromCandidates(
        candidates: Iterable<SkyblockId>,
        name: String, mayBeMangled: Boolean
    ): SkyblockId? {
        val expectedClean = name.removeColorCodes()
        var bestMatch: SkyblockId? = null
        var bestMatchLength = -1
        for (candidate in candidates) {
            val item = RepoManager.getNEUItem(candidate) ?: continue
            for (name in getAllNamesForItem(item)) {
                val actualClean = name.removeColorCodes()
                val matches = if (mayBeMangled) expectedClean == actualClean
                else expectedClean.contains(actualClean)
                if (!matches) continue
                if (actualClean.length > bestMatchLength) {
                    bestMatch = candidate
                    bestMatchLength = actualClean.length
                }
            }
        }
        return bestMatch
    }

}