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

package moe.nea.firmament.repo

import java.io.InputStream
import java.nio.file.Files
import java.nio.file.Path
import net.fabricmc.fabric.api.resource.ModResourcePack
import net.fabricmc.loader.api.FabricLoader
import net.fabricmc.loader.api.metadata.ModMetadata
import kotlin.io.path.exists
import kotlin.io.path.isRegularFile
import kotlin.io.path.relativeTo
import kotlin.streams.asSequence
import net.minecraft.resource.AbstractFileResourcePack
import net.minecraft.resource.InputSupplier
import net.minecraft.resource.ResourcePack
import net.minecraft.resource.ResourceType
import net.minecraft.resource.metadata.ResourceMetadataReader
import net.minecraft.util.Identifier
import net.minecraft.util.PathUtil

class RepoModResourcePack(val basePath: Path) : ModResourcePack {
    companion object {
        fun append(packs: MutableList<in ModResourcePack>) {
            packs.add(RepoModResourcePack(RepoDownloadManager.repoSavedLocation))
        }
    }

    override fun close() {
    }

    override fun openRoot(vararg segments: String): InputSupplier<InputStream>? {
        return getFile(segments)?.let { InputSupplier.create(it) }
    }

    fun getFile(segments: Array<out String>): Path? {
        PathUtil.validatePath(*segments)
        val path = segments.fold(basePath, Path::resolve)
        if (!path.isRegularFile()) return null
        return path
    }

    override fun open(type: ResourceType?, id: Identifier): InputSupplier<InputStream>? {
        if (type != ResourceType.CLIENT_RESOURCES) return null
        if (id.namespace != "neurepo") return null
        val file = getFile(id.path.split("/").toTypedArray())
        return file?.let { InputSupplier.create(it) }
    }

    override fun findResources(
        type: ResourceType?,
        namespace: String,
        prefix: String,
        consumer: ResourcePack.ResultConsumer
    ) {
        if (namespace != "neurepo") return
        if (type != ResourceType.CLIENT_RESOURCES) return

        val prefixPath = basePath.resolve(prefix)
        if (!prefixPath.exists())
            return
        Files.walk(prefixPath)
            .asSequence()
            .map { it.relativeTo(basePath) }
            .forEach {
                consumer.accept(Identifier.of("neurepo", it.toString()), InputSupplier.create(it))
            }
    }

    override fun getNamespaces(type: ResourceType?): Set<String> {
        if (type != ResourceType.CLIENT_RESOURCES) return emptySet()
        return setOf("neurepo")
    }

    override fun <T> parseMetadata(metaReader: ResourceMetadataReader<T>): T? {
        return AbstractFileResourcePack.parseMetadata(
            metaReader, """
{
    "pack": {
        "pack_format": 12,
        "description": "NEU Repo Resources"
    }
}
""".trimIndent().byteInputStream()
        )
    }

    override fun getName(): String {
        return "NEU Repo Resources"
    }

    override fun getFabricModMetadata(): ModMetadata {
        return FabricLoader.getInstance().getModContainer("firmament")
            .get().metadata
    }
}