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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
package moe.nea.firmament.repo
import java.io.InputStream
import java.nio.file.Files
import java.nio.file.Path
import java.util.Optional
import net.fabricmc.fabric.api.resource.ModResourcePack
import net.fabricmc.fabric.impl.resource.loader.ModResourcePackSorter
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.server.packs.AbstractPackResources
import net.minecraft.server.packs.resources.IoSupplier
import net.minecraft.server.packs.resources.FallbackResourceManager
import net.minecraft.server.packs.resources.Resource
import net.minecraft.server.packs.PackResources
import net.minecraft.server.packs.PackLocationInfo
import net.minecraft.server.packs.repository.PackSource
import net.minecraft.server.packs.PackType
import net.minecraft.server.packs.resources.ResourceMetadata
import net.minecraft.server.packs.metadata.MetadataSectionType
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.FileUtil
import moe.nea.firmament.Firmament
class RepoModResourcePack(val basePath: Path) : ModResourcePack {
companion object {
fun append(packs: ModResourcePackSorter) {
Firmament.logger.info("Registering mod resource pack")
packs.addPack(RepoModResourcePack(RepoDownloadManager.repoSavedLocation))
}
fun createResourceDirectly(identifier: ResourceLocation): Optional<Resource> {
val pack = RepoModResourcePack(RepoDownloadManager.repoSavedLocation)
return Optional.of(
Resource(
pack,
pack.getResource(PackType.CLIENT_RESOURCES, identifier) ?: return Optional.empty()
) {
val base =
pack.getResource(PackType.CLIENT_RESOURCES, identifier.withPath(identifier.path + ".mcmeta"))
if (base == null)
ResourceMetadata.EMPTY
else
FallbackResourceManager.parseMetadata(base)
}
)
}
}
override fun close() {
}
override fun getRootResource(vararg segments: String): IoSupplier<InputStream>? {
return getFile(segments)?.let { IoSupplier.create(it) }
}
fun getFile(segments: Array<out String>): Path? {
FileUtil.validatePath(*segments)
val path = segments.fold(basePath, Path::resolve)
if (!path.isRegularFile()) return null
return path
}
override fun getResource(type: PackType?, id: ResourceLocation): IoSupplier<InputStream>? {
if (type != PackType.CLIENT_RESOURCES) return null
if (id.namespace != "neurepo") return null
val file = getFile(id.path.split("/").toTypedArray())
return file?.let { IoSupplier.create(it) }
}
override fun listResources(
type: PackType?,
namespace: String,
prefix: String,
consumer: PackResources.ResourceOutput
) {
if (namespace != "neurepo") return
if (type != PackType.CLIENT_RESOURCES) return
val prefixPath = basePath.resolve(prefix)
if (!prefixPath.exists())
return
Files.walk(prefixPath)
.asSequence()
.map { it.relativeTo(basePath) }
.forEach {
consumer.accept(
ResourceLocation.tryBuild("neurepo", it.toString()) ?: return@forEach,
IoSupplier.create(it)
)
}
}
override fun getNamespaces(type: PackType?): Set<String> {
if (type != PackType.CLIENT_RESOURCES) return emptySet()
return setOf("neurepo")
}
override fun <T : Any?> getMetadataSection(metadataSerializer: MetadataSectionType<T>?): T? {
return AbstractPackResources.getMetadataFromStream(
metadataSerializer, """
{
"pack": {
"pack_format": 12,
"description": "NEU Repo Resources"
}
}
""".trimIndent().byteInputStream(), location()
)
}
override fun location(): PackLocationInfo {
return PackLocationInfo("neurepo", Component.literal("NEU Repo"), PackSource.BUILT_IN, Optional.empty())
}
override fun getFabricModMetadata(): ModMetadata {
return FabricLoader.getInstance().getModContainer("firmament")
.get().metadata
}
override fun createOverlay(overlay: String): ModResourcePack {
return RepoModResourcePack(basePath.resolve(overlay))
}
}
|