Skip to content

Commit 20ca3a3

Browse files
committed
optimization: only try to load resources from mods with the given namespace present
1 parent 91a22d5 commit 20ca3a3

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

src/main/java/org/mcsr/speedrunapi/mixin/resourceloader/DefaultResourcePackMixin.java renamed to src/main/java/org/mcsr/speedrunapi/mixin/resourceloader/DefaultClientResourcePackMixin.java

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,48 @@
1313
import org.spongepowered.asm.mixin.injection.ModifyArg;
1414
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1515

16+
import java.io.IOException;
1617
import java.io.InputStream;
17-
import java.util.ArrayList;
18-
import java.util.List;
18+
import java.nio.file.Files;
19+
import java.nio.file.Path;
20+
import java.util.*;
21+
import java.util.stream.Stream;
1922

2023
@Mixin(DefaultClientResourcePack.class)
21-
public abstract class DefaultResourcePackMixin {
22-
24+
public abstract class DefaultClientResourcePackMixin {
2325
@Unique
2426
private static final boolean HAS_FABRIC_RESOURCE_LOADER = FabricLoader.getInstance().isModLoaded("fabric-resource-loader-v0");
27+
@Unique
28+
private static final Map<String, Set<ModContainer>> NAMESPACES_TO_MODS = new HashMap<>();
29+
30+
static {
31+
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
32+
if (mod.getMetadata().getType().equals("builtin")) {
33+
continue;
34+
}
35+
mod.findPath("assets").filter(Files::isDirectory).ifPresent(assets -> {
36+
try (Stream<Path> stream = Files.list(assets)) {
37+
// skip empty namespace directories
38+
// some mods may have template directories left over
39+
if (!stream.findFirst().isPresent()) {
40+
return;
41+
}
42+
} catch (IOException ignored) {
43+
}
44+
45+
Set<String> namespaces = new HashSet<>();
46+
try (Stream<Path> stream = Files.list(assets)) {
47+
stream.filter(Files::isDirectory).forEach(path -> namespaces.add(path.getFileName().toString()));
48+
} catch (IOException e) {
49+
SpeedrunAPI.LOGGER.error("SpeedrunAPI failed to check resources for mod: {}", mod.getMetadata().getId());
50+
}
51+
52+
for (String namespace : namespaces) {
53+
NAMESPACES_TO_MODS.computeIfAbsent(namespace, key -> new TreeSet<>(Comparator.comparing(m -> m.getMetadata().getId(), String::compareTo))).add(mod);
54+
}
55+
});
56+
}
57+
}
2558

2659
@ModifyArg(
2760
method = "<init>",
@@ -30,36 +63,33 @@ public abstract class DefaultResourcePackMixin {
3063
target = "Lnet/minecraft/resource/DefaultResourcePack;<init>([Ljava/lang/String;)V"
3164
)
3265
)
33-
private static String[] addModNamespaces(String[] namespaces) {
66+
private static String[] initModsToNamespaces(String[] namespaces) {
3467
if (HAS_FABRIC_RESOURCE_LOADER) {
3568
SpeedrunAPI.LOGGER.info("Disabling SpeedrunAPI resource loader in favor of fabric-resource-loader.");
3669
return namespaces;
3770
}
3871

39-
List<ModContainer> mods = new ArrayList<>(FabricLoader.getInstance().getAllMods());
40-
mods.removeIf(mod -> mod.getMetadata().getType().equals("builtin"));
41-
42-
String[] allNamespaces = new String[mods.size() + namespaces.length];
43-
int i;
44-
for (i = 0; i < namespaces.length; i++) {
45-
allNamespaces[i] = namespaces[i];
46-
}
47-
for (ModContainer mod : mods) {
48-
allNamespaces[i++] = mod.getMetadata().getId();
49-
}
50-
return allNamespaces;
72+
Set<String> combined = new LinkedHashSet<>();
73+
combined.addAll(Arrays.asList(namespaces));
74+
combined.addAll(NAMESPACES_TO_MODS.keySet());
75+
return combined.toArray(new String[0]);
5176
}
5277

5378
@Inject(method = "findInputStream", at = @At("HEAD"), cancellable = true)
5479
private void loadModResources(ResourceType type, Identifier id, CallbackInfoReturnable<InputStream> cir) {
5580
if (HAS_FABRIC_RESOURCE_LOADER) {
5681
return;
5782
}
58-
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
59-
if (mod.getMetadata().getType().equals("builtin")) {
60-
continue;
61-
}
62-
mod.findPath(type.getDirectory() + "/" + id.getNamespace() + "/" + id.getPath()).ifPresent(path -> {
83+
// make sure only client resources are loaded
84+
if (type != ResourceType.CLIENT_RESOURCES) {
85+
return;
86+
}
87+
Set<ModContainer> mods = NAMESPACES_TO_MODS.get(id.getNamespace());
88+
if (mods == null) {
89+
return;
90+
}
91+
for (ModContainer mod : mods) {
92+
mod.findPath("assets/" + id.getNamespace() + "/" + id.getPath()).ifPresent(path -> {
6393
try {
6494
cir.setReturnValue(path.toUri().toURL().openStream());
6595
} catch (Exception e) {

src/main/resources/speedrunapi.mixins.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"client": [
99
"entrypoint.MinecraftClientMixin",
1010
"gui.OptionsScreenMixin",
11-
"resourceloader.DefaultResourcePackMixin"
11+
"resourceloader.DefaultClientResourcePackMixin"
1212
],
1313
"server": [
1414
"entrypoint.MinecraftDedicatedServerMixin"

0 commit comments

Comments
 (0)